update to 0.3.5

support ai chat
This commit is contained in:
jack ning
2024-08-06 08:18:01 +08:00
parent f1214442c5
commit 318da99fc2
1023 changed files with 31537 additions and 8598 deletions

4
.gitignore vendored
View File

@@ -25,10 +25,10 @@ hs_err_pid*
/starter/logs
h2db/
application-prod.properties
application-dev-mysql.properties
application-dev-pg.properties
application-prod-pg.properties
application-prod-mysql.properties
application-dev-pg-private.properties
application-dev-oracle.properties
projects/*
liangshibao/*
tiku/*

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 09:43:27
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-26 12:24:07
* @LastEditTime: 2024-08-06 07:52:10
* @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.
@@ -82,7 +82,7 @@ git clone https://github.com/Bytedesk/bytedesk.git
cd bytedesk
mvn install -Dmaven.test.skip=true
#
cd bytedesk/starter
cd starter
mvn spring-boot:run
#
# local preview:

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 09:44:23
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-28 13:19:25
* @LastEditTime: 2024-08-06 07:52: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.
@@ -87,7 +87,7 @@ git clone https://github.com/Bytedesk/bytedesk.git
cd bytedesk
mvn install -Dmaven.test.skip=true
#
cd bytedesk/starter
cd starter
mvn spring-boot:run
#
# 本地预览

BIN
modules/.DS_Store vendored

Binary file not shown.

BIN
modules/ai/.DS_Store vendored

Binary file not shown.

View File

@@ -6,58 +6,44 @@
<parent>
<groupId>com.bytedesk</groupId>
<artifactId>modules</artifactId>
<version>${revision}</version>
<artifactId>modules</artifactId>
<version>${revision}</version>
</parent>
<groupId>com.bytedesk</groupId>
<artifactId>bytedesk-module-ai</artifactId>
<version>${revision}</version>
<name>bytedesk-module-ai</name>
<description>Demo project for Spring Boot</description>
<description>ai module for https://www.weiyuai.cn</description>
<properties>
<!-- https://docs.spring.io/spring-ai/reference/getting-started.html -->
<!-- <spring-ai.version>1.0.0-M1</spring-ai.version> -->
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
</properties>
<dependencies>
<!-- <dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-chroma-store-spring-boot-starter</artifactId>
</dependency> -->
<artifactId>spring-ai-spring-boot-autoconfigure</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://docs.spring.io/spring-ai/reference/api/embeddings/ollama-embeddings.html -->
<!--
https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-ollama-spring-boot-starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-postgresml-spring-boot-starter</artifactId>
</dependency> -->
<!-- <dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
</dependency> -->
<!-- https://docs.spring.io/spring-ai/reference/api/embeddings/zhipuai-embeddings.html -->
<!-- Spring AI ZhiPuAI Auto Configuration -->
<!--
https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-zhipuai-spring-boot-starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<!-- ///////////////////////////////////////////////////////////////////////////// -->
@@ -69,6 +55,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bytedesk</groupId>
<artifactId>bytedesk-module-kbase</artifactId>
<version>${revision}</version>
<scope>provided</scope>
</dependency>
<!-- ///////////////////////////////////////////////////////////////////////////// -->
<!-- https://open.bigmodel.cn/dev/api#sdk_install -->
@@ -76,7 +69,15 @@
<dependency>
<groupId>cn.bigmodel.openapi</groupId>
<artifactId>oapi-java-sdk</artifactId>
<version>release-V4-2.1.0</version>
<version>release-V4-2.2.0</version>
</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>
<!-- ///////////////////////////////////////////////////////////////////////////// -->
@@ -87,6 +88,7 @@
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
@@ -98,7 +100,7 @@
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- <plugin>

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-02 09:32:36
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-31 09:58:27
* @LastEditTime: 2024-07-23 11:35:15
* @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,11 +12,13 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
-->
# ai
# ai module
## docs
- [spring-ai](https://docs.spring.io/spring-ai/reference/)
- [spring-ai](https://spring.io/projects/spring-ai)
- [spring-ai-docs](https://docs.spring.io/spring-ai/reference/index.html)
- [spring-ai-getting-started](https://docs.spring.io/spring-ai/reference/getting-started.html)
- [spring-ai-github](https://github.com/spring-projects/spring-ai)
```bash

26
modules/ai/readme.zh.md Normal file
View File

@@ -0,0 +1,26 @@
<!--
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-02 09:32:36
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-20 08:24: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.
-->
# AI 模块
## docs
- [spring-ai](https://spring.io/projects/spring-ai)
- [spring-ai-docs](https://docs.spring.io/spring-ai/reference/index.html)
- [spring-ai-getting-started](https://docs.spring.io/spring-ai/reference/getting-started.html)
- [spring-ai-github](https://github.com/spring-projects/spring-ai)
```bash
ollama --help
```

View File

@@ -1,77 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:21:15
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:15: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.doc;
import com.bytedesk.ai.file.KbFile;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.constant.TypeConsts;
import jakarta.persistence.Column;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Entity;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 文档
*
*/
@Entity
@Data
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ai_kb_doc")
public class KbDoc extends BaseEntity {
private static final long serialVersionUID = 1L;
@Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT)
private String content;
private String meta;
/**
*
*/
@JoinColumn(name = "kb_file_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
private KbFile kbFile;
/**
* belong to org
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// private Organization organization;
// private String orgUid;
/**
* 所属用户
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "none", value =
// ConstraintMode.NO_CONSTRAINT))
// private User user;
}

View File

@@ -1,34 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 17:00:21
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-03-26 16:28: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.ai.doc;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
// import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Repository;
import io.swagger.v3.oas.annotations.tags.Tag;
/**
*
* @Description: 知识库文档
* @Version: 1.0
*/
@Repository
@Tag(name = "kbdoc info - 知识库文档")
// @PreAuthorize("hasRole('ROLE_ADMIN')")
public interface KbDocRepository extends JpaRepository<KbDoc, Long>, JpaSpecificationExecutor<KbDoc> {
}

View File

@@ -1,84 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:23:35
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:15:52
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.file;
import com.bytedesk.ai.kb.Kb;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.upload.Upload;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 文件
*
*/
@Entity
@Data
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ai_kb_file")
public class KbFile extends BaseEntity {
private static final long serialVersionUID = 1L;
private String loader;
private String splitter;
private Integer docsCount;
@JoinColumn(name = "upload_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
private Upload upload;
/**
* 知识库
*/
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "kb_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
private Kb kb;
/**
* belong to org
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// private Organization organization;
// private String orgUid;
/**
* 所属用户
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
// private User user;
}

View File

@@ -1,68 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:48:26
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-09 10:48:34
* @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.file;
import org.springframework.http.ResponseEntity;
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.base.BaseController;
import lombok.AllArgsConstructor;
/**
*
*/
@RestController
@RequestMapping("/api/v1/kb/file")
@AllArgsConstructor
public class KbFileController extends BaseController<KbFileRequest> {
// private final KbFileService kbService;
@Override
public ResponseEntity<?> queryByOrg(KbFileRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'queryByOrg'");
}
@Override
public ResponseEntity<?> query(KbFileRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'query'");
}
@Override
public ResponseEntity<?> create(@RequestBody KbFileRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'create'");
}
@Override
public ResponseEntity<?> update(@RequestBody KbFileRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'update'");
}
@Override
public ResponseEntity<?> delete(@RequestBody KbFileRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'delete'");
}
}

View File

@@ -1,34 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:58:52
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-03-27 17:33: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.ai.file;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
// import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Repository;
import io.swagger.v3.oas.annotations.tags.Tag;
/**
* 知识库文件
*
*/
@Repository
@Tag(name = "kbfile info - 知识库文件")
// @PreAuthorize("hasRole('ROLE_ADMIN')")
public interface KbFileRepository extends JpaRepository<KbFile, Long>, JpaSpecificationExecutor<KbFile> {
}

View File

@@ -1,50 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:59:15
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-04 10:57: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.file;
import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import lombok.AllArgsConstructor;
@Service
@AllArgsConstructor
public class KbFileService {
private final KbFileRepository kbFileRepository;
private final ModelMapper modelMapper;
public Page<KbFileResponse> query(KbFileRequest kbFileRequest) {
Pageable pageable = PageRequest.of(kbFileRequest.getPageNumber(), kbFileRequest.getPageSize(),
Sort.Direction.DESC,
"id");
Page<KbFile> kbFiles = kbFileRepository.findAll(pageable);
return kbFiles.map(this::convertToKbFileResponse);
}
public KbFileResponse convertToKbFileResponse(KbFile kbFile) {
return modelMapper.map(kbFile, KbFileResponse.class);
}
}

View File

@@ -1,77 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:13:38
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-24 22:38:25
* @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.kb;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.enums.LanguageEnum;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 知识库
*
*/
@Entity
@Data
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ai_kb")
public class Kb extends BaseEntity {
private static final long serialVersionUID = 1L;
private String name;
private String vectorStore;
private String embeddings;
// is_published or not
@Builder.Default
private boolean published = true;
@Builder.Default
@Enumerated(EnumType.STRING)
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
/**
* belong to org
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// private Organization organization;
// private String orgUid;
/**
* 所属用户
*/
// @JsonIgnore
// @ManyToOne(fetch = FetchType.LAZY)
// @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
// private User user;
}

View File

@@ -1,80 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:46:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:16:12
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.kb;
import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import com.bytedesk.core.uid.UidUtils;
import com.bytedesk.core.utils.JsonResult;
import lombok.AllArgsConstructor;
@Service
@AllArgsConstructor
public class KbService {
private final KbRepository kbRepository;
private final ModelMapper modelMapper;
private final UidUtils uidUtils;
public Page<KbResponse> query(KbRequest kbRequest) {
Pageable pageable = PageRequest.of(kbRequest.getPageNumber(), kbRequest.getPageSize(), Sort.Direction.DESC,
"id");
Page<Kb> kbList = kbRepository.findAll(pageable);
//
return kbList.map(this::convertToKbResponse);
}
public JsonResult<?> create(KbRequest kbRequest) {
Kb kb = modelMapper.map(kbRequest, Kb.class);
kb.setUid(uidUtils.getCacheSerialUid());
// kb.setUser(authService.getCurrentUser());
kbRepository.save(kb);
return JsonResult.success();
}
public KbResponse convertToKbResponse(Kb kb) {
return modelMapper.map(kb, KbResponse.class);
}
public Kb getKb(String name, String orgUid) {
Kb kb = Kb.builder()
// .kid(uidUtils.getCacheSerialUid())
.name(name)
.vectorStore("redis")
.embeddings("m3e-base")
// .orgUid(orgUid)
.build();
kb.setUid(uidUtils.getCacheSerialUid());
kb.setOrgUid(orgUid);
return kbRepository.save(kb);
}
}

View File

@@ -1,9 +0,0 @@
package com.bytedesk.ai.keyword;
public enum KeywordMatchEnum {
EXACT, // 精确匹配
FUZZY, // 模糊匹配
REGULAR, // 正则匹配
VECTOR, // 向量匹配
ELASTIC; // ElasticSearch搜索引擎匹配
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-31 10:24:39
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-31 11:11:28
* @LastEditTime: 2024-07-29 11:04: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.
@@ -19,40 +19,74 @@ import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.ollama.OllamaEmbeddingModel;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* https://ollama.com/
* https://www.promptingguide.ai/
* https://docs.spring.io/spring-ai/reference/api/embeddings/ollama-embeddings.html
*/
@Configuration
public class OllamaConfig {
@Value("${spring.ai.ollama.base-url}")
private String ollamaBaseUrl;
@Value("${spring.ai.ollama.chat.options.model}")
private String ollamaChatModel;
@Value("${spring.ai.ollama.embedding.options.model}")
private String ollamaEmbeddingModel;
// @Value("${spring.ai.vectorstore.pgvector.dimensions}")
// private int pgVectorDimensions;
// @Autowired
// VectorStore vectorStore;
@Bean
OllamaApi ollamaApi() {
return new OllamaApi("http://127.0.0.1:11434");
return new OllamaApi(ollamaBaseUrl);
}
// https://docs.spring.io/spring-ai/reference/api/chatclient.html
// @Bean
// ChatClient chatClient(ChatClient.Builder builder) {
// // return builder.defaultSystem("You are a friendly chat bot that answers question").build();
// return builder
// .defaultSystem("""
// You are a customer chat support agent. Respond in a friendly, helpful, and joyful manner.
// """)
// // .defaultAdvisors(
// // // new PromptChatMemoryAdvisor(chatMemory),
// // // new MessageChatMemoryAdvisor(chatMemory), // CHAT MEMORY
// // // new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())
// // // new LoggingAdvisor()
// // ) // RAG
// // .defaultFunctions("getBookingDetails", "changeBooking", "cancelBooking") // FUNCTION CALLING
// .build();
// }
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("You are a friendly chat bot that answers question")
.build();
ChatClient ollamaChatClient() {
return ChatClient.create(ollamaChatModel());
}
@Bean
OllamaChatModel chatModel() {
return new OllamaChatModel(ollamaApi(),
OllamaOptions.create()
// .withModel(OllamaOptions.DEFAULT_MODEL)
.withModel("qwen:7b")
.withTemperature(0.9f));
@Primary
OllamaChatModel ollamaChatModel() {
return new OllamaChatModel(ollamaApi(), OllamaOptions.create().withModel(
ollamaChatModel).withTemperature(0.9f));
}
// https://docs.spring.io/spring-ai/reference/api/embeddings/ollama-embeddings.html
@Bean
@Primary
OllamaEmbeddingModel ollamaEmbeddingModel() {
return new OllamaEmbeddingModel(ollamaApi());
return new OllamaEmbeddingModel(ollamaApi(), OllamaOptions.create().withModel(
ollamaEmbeddingModel).withTemperature(0.9f));
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-31 09:50:56
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-31 11:12:19
* @LastEditTime: 2024-08-02 09:41: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.
@@ -15,17 +15,8 @@
package com.bytedesk.ai.ollama;
import java.util.List;
import java.util.Map;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.embedding.EmbeddingRequest;
import org.springframework.ai.embedding.EmbeddingResponse;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.ollama.OllamaEmbeddingModel;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -33,71 +24,121 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.bytedesk.core.utils.JsonResult;
import com.bytedesk.kbase.upload.UploadVectorStore;
import lombok.AllArgsConstructor;
import reactor.core.publisher.Flux;
import lombok.extern.slf4j.Slf4j;
// https://docs.spring.io/spring-ai/reference/api/chat/ollama-chat.html
@Slf4j
@RestController
@RequestMapping("/visitor/api/v1/ai/ollama")
@AllArgsConstructor
public class OllamaController {
private final OllamaEmbeddingModel ollamaEmbeddingModel;
private final ChatClient chatClient;
private final OllamaChatModel chatModel;
// private final ChatModel chatModel;
// public OllamaController(EmbeddingModel embeddingModel, ChatClient.Builder
// chatClientbBuilder) {
// this.embeddingModel = embeddingModel;
// this.chatClient = chatClientbBuilder.build();
// }
private final UploadVectorStore uploadVectorStore;
private final String PROMPT_BLUEPRINT = """
Answer the query strictly referring the provided context:
{context}
Query:
{query}
In case you don't have any answer from the context provided, just say:
I'm sorry I don't have the information you are looking for.
""";
// private final String PROMPT_BLUEPRINT = """
// 根据提供的文档信息回答问题,文档信息如下:
// {context}
// 问题:
// {query}
// 当用户提出的问题无法根据文档内容进行回复或者你也不清楚时,回复不知道即可.
// """;
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/simple?message=讲一个笑话
@GetMapping("/simple")
public ResponseEntity<?> getSimpleCompletion(
@RequestParam(value = "message", defaultValue = "讲一个笑话") String message) {
String content = chatClient.prompt().user(message).call().content();
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/chat?input=hello
@GetMapping("/chat")
public ResponseEntity<?> generation(@RequestParam("input") String input) {
String content = this.chatClient.prompt()
.user(input)
.call()
.content();
return ResponseEntity.ok(JsonResult.success(content));
}
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/simple
@GetMapping("/simple")
public Map<String, String> completion(
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("completion", chatClient.prompt().user(message).call().content());
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/rich
@GetMapping("/rich")
public ResponseEntity<?> getRichCompletion(
@RequestParam(value = "message", defaultValue = "讲一个笑话") String message) {
ChatResponse chatResponse = chatClient.prompt().user(message).call().chatResponse();
// ChatResponse chatResponse = chatModel.call(
// new Prompt(message,
// OllamaOptions.builder()
// .withModel(OllamaModel.MISTRAL)
// // .withTemperature(0.4)
// .build()));
return ResponseEntity.ok(JsonResult.success(chatResponse));
}
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/generate
@GetMapping("/generate")
public Map<?, ?> generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", chatModel.call(message));
}
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/generateStream
@GetMapping("/generateStream")
public Flux<ChatResponse> generateStream(
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return chatModel.stream(prompt);
}
/*
* http://127.0.0.1:9003/visitor/api/v1/ai/ollama/embedding
*/
@GetMapping("/embedding")
public Map<?, ?> embed(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
// EmbeddingResponse embeddingResponse =
// embeddingModel.embedForResponse(List.of(message));
// 参考
// https://github.com/habuma/spring-ai-rag-example/blob/main/src/main/java/com/example/springairag/AskController.java
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/chat?query=考试日期
@GetMapping("/chat")
public ResponseEntity<?> chat(@RequestParam(value = "query", defaultValue = "考试日期") String query) {
//
EmbeddingResponse embeddingResponse = ollamaEmbeddingModel
.call(new EmbeddingRequest(List.of("Hello World", "World is big and salvation is near"),
OllamaOptions.create().withModel("qwen:7b")));
List<String> contentList = uploadVectorStore.searchText(query);
return Map.of("embedding", embeddingResponse);
ChatResponse response = chatClient.prompt()
.user(userSpec -> userSpec
.text(PROMPT_BLUEPRINT)
.param("query", query)
.param("context", String.join("\n", contentList)))
.call()
.chatResponse();
log.info("chat response: {}", response);
String answer = response.getResult().getOutput().getContent();
//
return ResponseEntity.ok(JsonResult.success("chat success", answer));
}
// http://127.0.0.1:9003/visitor/api/v1/ai/ollama/chat/stream?query=考试日期
// @GetMapping("/chat/stream")
// public void chatStream(@RequestParam(value = "query", defaultValue = "考试日期") String query) {
// //
// List<String> contentList = uploadVectorStore.searchText(query);
// //
// SystemPromptTemplate promoptTemplate = new SystemPromptTemplate(PROMPT_BLUEPRINT);
// Message message = promoptTemplate.createMessage(Map.of("query", query, "context", contentList));
// log.info("query: {}, message {}", query, message);
// //
// chatModel.stream(new Prompt(message)).subscribe(response -> {
// log.info(query + " : " + response.getResult().getOutput().getContent());
// });
// }
// public Generation retrieve(String message) {
// SearchRequest request = SearchRequest.query(message).withTopK(topK);
// // Query Redis for the top K documents most relevant to the input message
// List<Document> docs = store.similaritySearch(request);
// Message systemMessage = getSystemMessage(docs);
// UserMessage userMessage = new UserMessage(message);
// // Assemble the complete prompt using a template
// Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
// // Call the autowired chat client with the prompt
// ChatResponse response = client.call(prompt);
// return response.getResult();
// }
// // end::retrieve[]
// private Message getSystemMessage(List<Document> similarDocuments) {
// String documents =
// similarDocuments.stream().map(Document::getContent).collect(Collectors.joining("\n"));
// SystemPromptTemplate systemPromptTemplate = new
// SystemPromptTemplate(systemBeerPrompt);
// return systemPromptTemplate.createMessage(Map.of("documents", documents));
// }
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:16:26
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-06 13:14:24
* @LastEditTime: 2024-08-02 22:14:15
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -17,7 +17,6 @@ package com.bytedesk.ai.robot;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import com.bytedesk.ai.kb.Kb;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.constant.AvatarConsts;
@@ -25,19 +24,12 @@ import com.bytedesk.core.constant.BdConstants;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.enums.LevelEnum;
import com.bytedesk.core.rbac.user.User;
import com.fasterxml.jackson.annotation.JsonIgnore;
// import jakarta.persistence.AssociationOverride;
// import jakarta.persistence.AssociationOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
@@ -99,17 +91,11 @@ public class Robot extends BaseEntity {
@JdbcTypeCode(SqlTypes.JSON)
private String flow = BdConstants.EMPTY_JSON_STRING;
// is_published or not
@Builder.Default
private boolean published = false;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
private Kb kb;
private String kbUid; // 对应知识库
// only used when created by user, not by org
@JsonIgnore
@ManyToOne
private User user;
// private String userUid; // 创建用户
}

View File

@@ -14,28 +14,28 @@
*/
package com.bytedesk.ai.robot;
public enum RobotEmbedingEnum {
M3E_BASE("m3e-base");
// embedings无法枚举只能使用字符串
// public enum RobotEmbedingEnum {
// M3E_BASE("m3e-base");
// private final String value;
private final String value;
// RobotEmbedingEnum(String value) {
// this.value = value;
// }
RobotEmbedingEnum(String value) {
this.value = value;
}
// // 获取枚举常量的整型值
// public String getValue() {
// return value;
// }
// 获取枚举常量的整型值
public String getValue() {
return value;
}
// 根据整型值查找对应的枚举常量
public static RobotEmbedingEnum fromValue(String value) {
for (RobotEmbedingEnum type : RobotEmbedingEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
return type;
}
}
throw new IllegalArgumentException("No RobotEmbedingEnum constant with value " + value);
}
}
// // 根据整型值查找对应的枚举常量
// public static RobotEmbedingEnum fromValue(String value) {
// for (RobotEmbedingEnum type : RobotEmbedingEnum.values()) {
// if (type.getValue().equalsIgnoreCase(value)) {
// return type;
// }
// }
// throw new IllegalArgumentException("No RobotEmbedingEnum constant with value " + value);
// }
// }

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-12 07:17:13
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-29 20:00:35
* @LastEditTime: 2024-08-04 10:46:16
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -14,16 +14,40 @@
*/
package com.bytedesk.ai.robot;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.SerializationUtils;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.bytedesk.ai.zhipuai.ZhipuaiService;
import com.bytedesk.core.config.BytedeskEventPublisher;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.ClientEnum;
import com.bytedesk.core.message.MessageExtra;
import com.bytedesk.core.message.MessageJsonEvent;
import com.bytedesk.core.message.MessageProtoEvent;
import com.bytedesk.core.message.MessageProtobuf;
import com.bytedesk.core.message.MessageStatusEnum;
import com.bytedesk.core.message.MessageTypeEnum;
import com.bytedesk.core.rbac.organization.Organization;
import com.bytedesk.core.rbac.organization.OrganizationCreateEvent;
import com.bytedesk.core.rbac.user.UserProtobuf;
import com.bytedesk.core.socket.protobuf.model.MessageProto;
import com.bytedesk.core.thread.ThreadProtobuf;
import com.bytedesk.core.thread.ThreadTypeEnum;
import com.bytedesk.core.uid.UidUtils;
import com.bytedesk.core.utils.MessageConvertUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -34,8 +58,11 @@ public class RobotEventListener {
private final RobotService robotService;
// private final KbService kbService;
// private final UidUtils uidUtils;
private final ZhipuaiService zhipuaiService;
private final BytedeskEventPublisher bytedeskEventPublisher;
private final UidUtils uidUtils;
@Order(5)
@EventListener
@@ -49,10 +76,10 @@ public class RobotEventListener {
orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_1,
orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_2);
//
List<String> quickButtonUids = Arrays.asList(
orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_1,
orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_2);
//
// List<String> quickButtonUids = Arrays.asList(
// orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_1,
// orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_2);
//
RobotRequest robotRequest = RobotRequest.builder()
.nickname(I18Consts.I18N_ROBOT_NICKNAME)
.description(I18Consts.I18N_ROBOT_DESCRIPTION)
@@ -61,30 +88,106 @@ public class RobotEventListener {
.build();
robotRequest.setType(RobotTypeEnum.SERVICE.name());
robotRequest.setOrgUid(orgUid);
//
//
robotRequest.getServiceSettings().setFaqUids(faqUids);
robotRequest.getServiceSettings().setQuickButtonUids(quickButtonUids);
//
robotRequest.getServiceSettings().setQuickFaqUids(faqUids);
//
robotService.create(robotRequest);
//
// Kb kb = kbService.getKb(I18Consts.I18N_ROBOT_NICKNAME, organization.getUid());
// RobotLlm llm = RobotLlm.builder().build();
// Robot robot = Robot.builder()
// // .nickname(I18Consts.I18N_ROBOT_NICKNAME)
// .description(I18Consts.I18N_ROBOT_DESCRIPTION)
// .type(RobotTypeEnum.SERVICE)
// // .orgUid(organization.getUid())
// .kb(kb)
// .llm(llm)
// .build();
// robot.setUid(uidUtils.getCacheSerialUid());
// robot.setOrgUid(orgUid);
// robot.setNickname(I18Consts.I18N_ROBOT_NICKNAME);
// robot.setAvatar(AvatarConsts.DEFAULT_AVATAR_URL);
// robotService.save(robot);
}
@EventListener
public void onMessageJsonEvent(MessageJsonEvent event) {
// log.info("MessageJsonEvent {}", event.getJson());
String messageJson = event.getJson();
//
processMessage(messageJson);
}
@EventListener
public void onMessageProtoEvent(MessageProtoEvent event) {
// log.info("MessageProtoEvent");
try {
MessageProto.Message messageProto = MessageProto.Message.parseFrom(event.getMessageBytes());
//
try {
String messageJson = MessageConvertUtils.toJson(messageProto);
//
processMessage(messageJson);
} catch (IOException e) {
e.printStackTrace();
}
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
private void processMessage(String messageJson) {
MessageProtobuf messageProtobuf = JSON.parseObject(messageJson, MessageProtobuf.class);
MessageTypeEnum messageType = messageProtobuf.getType();
String query = messageProtobuf.getContent();
log.info("robot processMessage {}", query);
//
ThreadProtobuf thread = messageProtobuf.getThread();
if (thread == null) {
throw new RuntimeException("thread is null");
}
// 仅针对文本类型自动回复
if (!messageType.equals(MessageTypeEnum.TEXT)) {
return;
}
//
String threadTopic = thread.getTopic();
log.info("robot threadTopic {}, thread.type {}", threadTopic, thread.getType());
if (thread.getType().equals(ThreadTypeEnum.ROBOT)) {
// 机器人回复
log.info("robot thread reply");
// 机器人客服消息 org/robot/default_robot_uid/1420995827073219
String[] splits = threadTopic.split("/");
if (splits.length < 4) {
throw new RuntimeException("robot topic format error");
}
String robotUid = splits[2];
if (!StringUtils.hasText(robotUid)) {
throw new RuntimeException("robotUid is null");
}
Optional<Robot> robotOptional = robotService.findByUid(robotUid);
if (robotOptional.isPresent()) {
Robot robot = robotOptional.get();
//
UserProtobuf user = UserProtobuf.builder().build();
user.setUid(robotUid);
user.setNickname(robot.getNickname());
user.setAvatar(robot.getAvatar());
//
MessageExtra extra = MessageExtra.builder()
// .isAutoReply(true)
// .autoReplyType(autoReplySettings.getAutoReplyType().name())
.orgUid(robot.getOrgUid())
.build();
//
MessageProtobuf message = MessageProtobuf.builder()
.uid(uidUtils.getCacheSerialUid())
.status(MessageStatusEnum.SUCCESS)
.thread(thread)
.user(user)
.client(ClientEnum.SYSTEM_AUTO)
.extra(JSONObject.toJSONString(extra))
.createdAt(new Date())
.build();
// 返回一个输入中消息,让访客端显示输入中
MessageProtobuf clonedMessage = SerializationUtils.clone(message);
clonedMessage.setUid(uidUtils.getCacheSerialUid());
clonedMessage.setType(MessageTypeEnum.PROCESSING);
String json = JSON.toJSONString(clonedMessage);
bytedeskEventPublisher.publishMessageJsonEvent(json);
// 绑定知识库
zhipuaiService.sendWsAutoReply(query, robot.getKbUid(), message);
} else {
log.error("robot not found");
}
}
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 10:02:51
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-06 13:27:21
* @LastEditTime: 2024-07-25 06:55: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.
@@ -19,8 +19,6 @@ import com.bytedesk.core.constant.TypeConsts;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -45,15 +43,16 @@ public class RobotLlm {
@Builder.Default
private Double scoreThreshold = 0.5;
@Builder.Default
@Enumerated(EnumType.STRING)
private RobotModelEnum model = RobotModelEnum.ZHIPUAI_GLM_3_TURBO;
@Builder.Default
@Enumerated(EnumType.STRING)
// private String embeddings = "m3e-base";
private RobotEmbedingEnum embeddings = RobotEmbedingEnum.M3E_BASE;
// @Enumerated(EnumType.STRING)
private String model = "ZHIPUAI_GLM_3_TURBO";
// private RobotModelEnum model = RobotModelEnum.ZHIPUAI_GLM_3_TURBO;
// @Builder.Default
// // @Enumerated(EnumType.STRING)
// private String embeddings = "M3E_BASE";
// // private RobotEmbedingEnum embeddings = RobotEmbedingEnum.M3E_BASE;
@Builder.Default
private float temperature = 0.9f;
@@ -64,6 +63,8 @@ public class RobotLlm {
@Builder.Default
@Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT)
private String prompt = I18Consts.I18N_ROBOT_LLM_PROMPT;
// private String promptTemplate =
// "请根据上下文信息回答问题:\n\n上下文信息\n{context}\n\n问题{question}\n\n答案";
// 上下文消息数默认3条。一同传递给大模型
@Builder.Default

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 12:41:13
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-06 12:09:38
* @LastEditTime: 2024-08-02 13:08:52
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -14,8 +14,10 @@
*/
package com.bytedesk.ai.robot;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 转化为json存储到message表中content字段
@@ -23,6 +25,8 @@ import lombok.Data;
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RobotMessage {
//
private String question;

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 10:42:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-06 13:12:14
* @LastEditTime: 2024-07-20 11:07: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.
@@ -14,48 +14,33 @@
*/
package com.bytedesk.ai.robot;
public enum RobotModelEnum {
ZHIPUAI_GLM_3_TURBO("glm-3-turbo"),
ZHIPUAI_GLM_4("GLM-4"),
ZHIPUAI_CogView("cogview"),
ZHIPUAI_GLM4V("glm-4v"),
OLLAMA("ollama"),
OPENAI("openai");
// model无法枚举只能通过字符串来指定
// public enum RobotModelEnum {
// ZHIPUAI_GLM_3_TURBO("glm-3-turbo"),
// ZHIPUAI_GLM_4("GLM-4"),
// ZHIPUAI_CogView("cogview"),
// ZHIPUAI_GLM4V("glm-4v"),
// OLLAMA("ollama"),
// OPENAI("openai");
// private final String name;
private final String value;
// private final String value;
RobotModelEnum(String value) {
// this.name = name;
this.value = value;
}
// RobotModelEnum(String value) {
// // this.name = name;
// this.value = value;
// }
// // 获取枚举常量的整型值
// public String getValue() {
// return value;
// }
// public String getName() {
// return name;
// }
// 获取枚举常量的整型值
public String getValue() {
return value;
}
// 根据整型值查找对应的枚举常量
public static RobotModelEnum fromValue(String value) {
for (RobotModelEnum type : RobotModelEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
return type;
}
}
throw new IllegalArgumentException("No RobotModelEnum constant with value " + value);
}
// public static RobotModelEnum fromString(String typeStr) {
// // 使用try-catch处理可能的异常
// try {
// return RobotModelEnum.valueOf(typeStr);
// } catch (IllegalArgumentException e) {
// // 处理错误,例如记录日志或抛出更具体的异常
// throw new IllegalArgumentException("Invalid robot type: " + typeStr, e);
// }
// }
}
// // 根据整型值查找对应的枚举常量
// public static RobotModelEnum fromValue(String value) {
// for (RobotModelEnum type : RobotModelEnum.values()) {
// if (type.getValue().equalsIgnoreCase(value)) {
// return type;
// }
// }
// throw new IllegalArgumentException("No RobotModelEnum constant with value " + value);
// }
// }

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:45:07
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-06 13:13:08
* @LastEditTime: 2024-08-02 22:15:05
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -55,6 +55,6 @@ public class RobotRequest extends BaseRequest {
@Builder.Default
private Boolean published = false;
private String kbUid; // 对应知识库
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:45:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-06 13:13:18
* @LastEditTime: 2024-08-02 22:15:15
* @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.
@@ -49,4 +49,6 @@ public class RobotResponse extends BaseResponse {
private RobotLlm llm;
private String defaultReply;
private String kbUid; // 对应知识库
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:44:41
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-08 11:08:42
* @LastEditTime: 2024-08-02 22:16:34
* @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.
@@ -33,12 +33,12 @@ import org.springframework.util.StringUtils;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.base.BaseService;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.quick_button.QuickButton;
import com.bytedesk.core.quick_button.QuickButtonService;
import com.bytedesk.core.rbac.user.UserConsts;
// import com.bytedesk.core.quick_button.QuickButton;
// import com.bytedesk.core.quick_button.QuickButtonService;
import com.bytedesk.core.constant.BdConstants;
import com.bytedesk.core.uid.UidUtils;
import com.bytedesk.core.faq.Faq;
import com.bytedesk.core.faq.FaqService;
import com.bytedesk.kbase.faq.Faq;
import com.bytedesk.kbase.faq.FaqService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -51,8 +51,7 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
private final RobotRepository robotRepository;
// private final KbService kbService;
private final QuickButtonService quickButtonService;
// private final QuickButtonService quickButtonService;
private final FaqService faqService;
@@ -67,6 +66,7 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
"updatedAt");
Specification<Robot> specification = RobotSpecification.search(request);
Page<Robot> page = robotRepository.findAll(specification, pageable);
return page.map(robot -> modelMapper.map(robot, RobotResponse.class));
@@ -99,26 +99,29 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
robot.setType(RobotTypeEnum.fromValue(request.getType()));
robot.setOrgUid(request.getOrgUid());
robot.setLlm(llm);
//
if (request.getServiceSettings() != null
&& request.getServiceSettings().getQuickButtonUids() != null
&& request.getServiceSettings().getQuickButtonUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getQuickButtonUids().iterator();
while (iterator.hasNext()) {
String quickButtonUid = iterator.next();
Optional<QuickButton> quickButtonOptional = quickButtonService.findByUid(quickButtonUid);
if (quickButtonOptional.isPresent()) {
QuickButton quickButtonEntity = quickButtonOptional.get();
log.info("quickButtonUid added: {}", quickButtonUid);
//
// if (request.getServiceSettings() != null
// && request.getServiceSettings().getQuickButtonUids() != null
// && request.getServiceSettings().getQuickButtonUids().size() > 0) {
// Iterator<String> iterator =
// request.getServiceSettings().getQuickButtonUids().iterator();
// while (iterator.hasNext()) {
// String quickButtonUid = iterator.next();
// Optional<QuickButton> quickButtonOptional =
// quickButtonService.findByUid(quickButtonUid);
// if (quickButtonOptional.isPresent()) {
// QuickButton quickButtonEntity = quickButtonOptional.get();
// log.info("quickButtonUid added: {}", quickButtonUid);
robot.getServiceSettings().getQuickButtons().add(quickButtonEntity);
} else {
throw new RuntimeException("quickButtonUid " + quickButtonUid + " not found");
}
}
} else {
log.info("robot quickButtonUid is null");
}
// robot.getServiceSettings().getQuickButtons().add(quickButtonEntity);
// } else {
// throw new RuntimeException("quickButtonUid " + quickButtonUid + " not
// found");
// }
// }
// } else {
// log.info("robot quickButtonUid is null");
// }
//
if (request.getServiceSettings() != null
&& request.getServiceSettings().getFaqUids() != null
@@ -140,6 +143,23 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
log.info("robot faquids is null");
}
if (request.getServiceSettings() != null
&& request.getServiceSettings().getQuickFaqUids() != null
&& request.getServiceSettings().getQuickFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getQuickFaqUids().iterator();
while (iterator.hasNext()) {
String quickFaqUid = iterator.next();
Optional<Faq> quickFaqOptional = faqService.findByUid(quickFaqUid);
if (quickFaqOptional.isPresent()) {
Faq quickFaqEntity = quickFaqOptional.get();
log.info("quickFaqUid added {}", quickFaqUid);
robot.getServiceSettings().getQuickFaqs().add(quickFaqEntity);
} else {
throw new RuntimeException("quickFaq " + quickFaqUid + " not found");
}
}
}
Robot updatedRobot = save(robot);
if (updatedRobot == null) {
throw new RuntimeException("save robot failed");
@@ -149,45 +169,27 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
}
@Override
public RobotResponse update(RobotRequest robotRequest) {
public RobotResponse update(RobotRequest request) {
Optional<Robot> robotOptional = findByUid(robotRequest.getUid());
Optional<Robot> robotOptional = findByUid(request.getUid());
if (!robotOptional.isPresent()) {
throw new RuntimeException("robot " + robotRequest.getUid() + " not found");
throw new RuntimeException("robot " + request.getUid() + " not found");
}
//
Robot robot = robotOptional.get();
robot.setNickname(robotRequest.getNickname());
robot.setAvatar(robotRequest.getAvatar());
robot.setDescription(robotRequest.getDescription());
robot.setPublished(robotRequest.getPublished());
robot.setDefaultReply(robotRequest.getDefaultReply());
robot.setNickname(request.getNickname());
robot.setAvatar(request.getAvatar());
robot.setDescription(request.getDescription());
robot.setPublished(request.getPublished());
robot.setDefaultReply(request.getDefaultReply());
robot.setKbUid(request.getKbUid());
//
RobotServiceSettings serviceSettings = modelMapper.map(
robotRequest.getServiceSettings(), RobotServiceSettings.class);
//
if (robotRequest.getServiceSettings().getQuickButtonUids() != null
&& robotRequest.getServiceSettings().getQuickButtonUids().size() > 0) {
Iterator<String> iterator = robotRequest.getServiceSettings().getQuickButtonUids().iterator();
while (iterator.hasNext()) {
String quickButtonUid = iterator.next();
Optional<QuickButton> quickButtonOptional = quickButtonService.findByUid(quickButtonUid);
if (quickButtonOptional.isPresent()) {
QuickButton quickButtonEntity = quickButtonOptional.get();
log.info("quickButtonUid added: {}", quickButtonUid);
serviceSettings.getQuickButtons().add(quickButtonEntity);
} else {
throw new RuntimeException("quickButtonUid " + quickButtonUid + " not found");
}
}
} else {
log.info("robot quickButtonUid is null");
}
request.getServiceSettings(), RobotServiceSettings.class);
//
if (robotRequest.getServiceSettings().getFaqUids() != null
&& robotRequest.getServiceSettings().getFaqUids().size() > 0) {
Iterator<String> iterator = robotRequest.getServiceSettings().getFaqUids().iterator();
if (request.getServiceSettings().getFaqUids() != null
&& request.getServiceSettings().getFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getFaqUids().iterator();
while (iterator.hasNext()) {
String faqUid = iterator.next();
Optional<Faq> faqOptional = faqService.findByUid(faqUid);
@@ -200,13 +202,28 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
throw new RuntimeException("faq " + faqUid + " not found");
}
}
} else {
log.info("robot faquids is null");
}
//
if (robotRequest.getServiceSettings().getGuessFaqUids() != null
&& robotRequest.getServiceSettings().getGuessFaqUids().size() > 0) {
Iterator<String> iterator = robotRequest.getServiceSettings().getGuessFaqUids().iterator();
if (request.getServiceSettings() != null
&& request.getServiceSettings().getQuickFaqUids() != null
&& request.getServiceSettings().getQuickFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getQuickFaqUids().iterator();
while (iterator.hasNext()) {
String quickFaqUid = iterator.next();
Optional<Faq> quickFaqOptional = faqService.findByUid(quickFaqUid);
if (quickFaqOptional.isPresent()) {
Faq quickFaqEntity = quickFaqOptional.get();
log.info("quickFaqUid added {}", quickFaqUid);
serviceSettings.getQuickFaqs().add(quickFaqEntity);
} else {
throw new RuntimeException("quickFaq " + quickFaqUid + " not found");
}
}
}
//
if (request.getServiceSettings().getGuessFaqUids() != null
&& request.getServiceSettings().getGuessFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getGuessFaqUids().iterator();
while (iterator.hasNext()) {
String guessFaqUid = iterator.next();
Optional<Faq> guessFaqOptional = faqService.findByUid(guessFaqUid);
@@ -214,16 +231,15 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
Faq guessFaq = guessFaqOptional.get();
log.info("guessFaqUid added {}", guessFaqUid);
serviceSettings.getGuessFaqs().add(guessFaq);
}
else {
} else {
throw new RuntimeException("guessFaq " + guessFaqUid + " not found");
}
}
}
//
if (robotRequest.getServiceSettings().getHotFaqUids()!= null
&& robotRequest.getServiceSettings().getHotFaqUids().size() > 0) {
Iterator<String> iterator = robotRequest.getServiceSettings().getHotFaqUids().iterator();
//
if (request.getServiceSettings().getHotFaqUids() != null
&& request.getServiceSettings().getHotFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getHotFaqUids().iterator();
while (iterator.hasNext()) {
String hotFaqUid = iterator.next();
Optional<Faq> hotFaqOptional = faqService.findByUid(hotFaqUid);
@@ -236,10 +252,10 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
}
}
}
//
if (robotRequest.getServiceSettings().getShortcutFaqUids() != null
&& robotRequest.getServiceSettings().getShortcutFaqUids().size() > 0) {
Iterator<String> iterator = robotRequest.getServiceSettings().getShortcutFaqUids().iterator();
//
if (request.getServiceSettings().getShortcutFaqUids() != null
&& request.getServiceSettings().getShortcutFaqUids().size() > 0) {
Iterator<String> iterator = request.getServiceSettings().getShortcutFaqUids().iterator();
while (iterator.hasNext()) {
String shortcutFaqUid = iterator.next();
Optional<Faq> shortcutFaqOptional = faqService.findByUid(shortcutFaqUid);
@@ -252,10 +268,10 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
}
}
}
//
//
robot.setServiceSettings(serviceSettings);
//
robot.setLlm(robotRequest.getLlm());
robot.setLlm(request.getLlm());
//
Robot updateRobot = save(robot);
if (updateRobot == null) {
@@ -318,17 +334,13 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
return;
}
//
String orgUid = UserConsts.DEFAULT_ORGANIZATION_UID;
String orgUid = BdConstants.DEFAULT_ORGANIZATION_UID;
List<String> faqUids = Arrays.asList(
orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_1,
orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_2);
//
List<String> quickButtonUids = Arrays.asList(
orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_1,
orgUid + I18Consts.I18N_QUICK_BUTTON_DEMO_TITLE_2);
//
// Kb kb = kbService.getKb(I18Consts.I18N_ROBOT_NICKNAME,
// UserConsts.DEFAULT_ORGANIZATION_UID);
// BdConstants.DEFAULT_ORGANIZATION_UID);
// RobotLlm llm = RobotLlm.builder().build();
RobotRequest robotRequest = RobotRequest.builder()
.nickname(I18Consts.I18N_ROBOT_NICKNAME)
@@ -336,12 +348,12 @@ public class RobotService extends BaseService<Robot, RobotRequest, RobotResponse
// .kb(kb)
// .llm(llm)
.build();
robotRequest.setUid(UserConsts.DEFAULT_ROBOT_UID);
robotRequest.setUid(BdConstants.DEFAULT_ROBOT_UID);
robotRequest.setType(RobotTypeEnum.SERVICE.name());
robotRequest.setOrgUid(UserConsts.DEFAULT_ORGANIZATION_UID);
robotRequest.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
//
robotRequest.getServiceSettings().setFaqUids(faqUids);
robotRequest.getServiceSettings().setQuickButtonUids(quickButtonUids);
robotRequest.getServiceSettings().setQuickFaqUids(faqUids);
//
create(robotRequest);
// save(robotRequest);

View File

@@ -1,28 +1,29 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 11:10:06
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-24 14:11:39
* @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;
public enum RobotTypeEnum {
SERVICE("service"), // 客服机器人
MARKETING("marketing"), // 营销机器人
KNOWLEDGEBASE("knowledgebase"), // 知识库机器人
QA("qa"); // 问答机器人
//
private final String value;
// 枚举构造器,每个枚举常量都有一个与之关联的整型值
RobotTypeEnum(String value) {
this.value = value;
}
// 获取枚举常量的整型值
public String getValue() {
return value;
}
SERVICE, // 客服机器人
MARKETING, // 营销机器人
KNOWLEDGEBASE, // 知识库机器人
QA; // 问答机器人
// 根据整型值查找对应的枚举常量
public static RobotTypeEnum fromValue(String value) {
for (RobotTypeEnum type : RobotTypeEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-06 11:08:52
* @LastEditTime: 2024-07-23 12:37: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.
@@ -15,7 +15,7 @@
package com.bytedesk.ai.settings;
import com.bytedesk.core.thread.ThreadTypeEnum;
import com.bytedesk.core.service_settings.BaseServiceSettings;
import com.bytedesk.kbase.service_settings.BaseServiceSettings;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;

View File

@@ -15,7 +15,7 @@
package com.bytedesk.ai.settings;
import com.bytedesk.core.thread.ThreadTypeEnum;
import com.bytedesk.core.service_settings.BaseServiceSettingsRequest;
import com.bytedesk.kbase.service_settings.BaseServiceSettingsRequest;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;

View File

@@ -15,7 +15,7 @@
package com.bytedesk.ai.settings;
import com.bytedesk.core.thread.ThreadTypeEnum;
import com.bytedesk.core.service_settings.BaseServiceSettingsResponse;
import com.bytedesk.kbase.service_settings.BaseServiceSettingsResponse;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;

View File

@@ -20,7 +20,7 @@ import com.bytedesk.ai.robot.Robot;
import com.bytedesk.ai.robot.RobotResponse;
import com.bytedesk.ai.robot.RobotProtobuf;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.service_settings.ServiceSettingsResponseVisitor;
import com.bytedesk.kbase.service_settings.ServiceSettingsResponseVisitor;
public class ConvertAiUtils {
private ConvertAiUtils() {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-31 10:53:11
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-31 11:17:06
* @LastEditTime: 2024-07-23 09:00:08
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -28,17 +28,17 @@ import org.springframework.context.annotation.Configuration;
import com.zhipu.oapi.ClientV4;
/**
* https://docs.spring.io/spring-ai/reference/api/chat/zhipuai-chat.html
* https://docs.spring.io/spring-ai/reference/api/embeddings/zhipuai-embeddings.html
*/
@Configuration
public class ZhipuAiConfig {
public class ZhipuaiConfig {
@Value("${spring.ai.zhipu.api-key}")
@Value("${spring.ai.zhipuai.api-key}")
String zhiPuAiApiKey;
@Bean
ZhiPuAiApi zhipuaiApi() {
// return new ZhiPuAiApi(System.getenv("ZHIPU_AI_API_KEY"));
return new ZhiPuAiApi(zhiPuAiApiKey);
}

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-14 13:55:30
* @LastEditTime: 2024-08-02 10:03:06
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -14,11 +14,11 @@
*/
package com.bytedesk.ai.zhipuai;
import java.util.Map;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.image.ImagePrompt;
@@ -36,9 +36,12 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import com.bytedesk.core.utils.JsonResult;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
/**
* https://open.bigmodel.cn/dev/api#sdk_install
@@ -50,13 +53,13 @@ import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/visitor/api/v1/zhipuai")
@AllArgsConstructor
public class ZhipuAiController {
public class ZhipuaiController {
private final ZhiPuAiChatModel chatModel;
private final ZhiPuAiImageModel zhiPuAiImageModel;
private final ZhipuAiService zhipuAiService;
private final ZhipuaiService zhipuaiService;
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/chat
@GetMapping("/chat")
@@ -71,20 +74,6 @@ public class ZhipuAiController {
return ResponseEntity.ok(JsonResult.success(response));
}
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/generate?content=hello
@GetMapping("/generate")
public Map<?, ?> generate(@RequestParam(value = "content", defaultValue = "讲个笑话") String content) {
return Map.of("generation", chatModel.call(content));
}
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/generateStream?content=讲个笑话
@GetMapping("/generateStream")
public Flux<ChatResponse> generateStream(
@RequestParam(value = "content", defaultValue = "讲个笑话") String content) {
var prompt = new Prompt(new UserMessage(content));
return chatModel.stream(prompt);
}
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/image
@GetMapping("/image")
public ResponseEntity<?> image() {
@@ -104,13 +93,51 @@ public class ZhipuAiController {
// TODO: 根据uid和ip判断此visitor是否骚扰用户如果骚扰则拒绝响应
log.info("sseEndpoint sid: {}, uid: {}, question {}", sid, uid, question);
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
executorService.submit(() -> {
try {
// 调用你的服务方法来获取SSE数据
zhipuAiService.getSseAnswer(uid, sid, question, emitter);
zhipuaiService.getSseAnswer(uid, sid, question, emitter);
// 将数据作为SSE事件发送
// emitter.send(SseEmitter.event().data(sseData));
// 完成后完成SSE流
// emitter.complete();
} catch (Exception e) {
// 如果发生错误,则发送错误事件
// emitter.send(SseEmitter.event().error(e));
emitter.completeWithError(e);
} finally {
// 确保清理资源
emitter.complete();
}
});
return ResponseEntity.ok().body(emitter);
}
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/sse/test
@GetMapping(value = "/sse/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public ResponseEntity<SseEmitter> sseTest(@RequestParam(value = "q", defaultValue = "讲个笑话") String question) {
log.info("sseTest question {}", question);
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
executorService.submit(() -> {
try {
for (int i = 0; i < 10; i++) {
// 将数据作为SSE事件发送
String sseData = "emitter: " + System.currentTimeMillis() + "\n\n";
// emitter.send(sseData);
emitter.send(
SseEmitter.event().name("testname").id(String.valueOf(i)).comment("comment").data(sseData));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 完成后完成SSE流
emitter.complete();
//
// 将数据作为SSE事件发送
// emitter.send(SseEmitter.event().data(sseData));
@@ -134,4 +161,25 @@ public class ZhipuAiController {
executorService.shutdown();
}
// http://127.0.0.1:9003/visitor/api/v1/zhipuai/stream-sse
@GetMapping("/stream-sse")
public void streamSse(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
for (int i = 0; i < 10; i++) {
writer.write("data: " + System.currentTimeMillis() + "\n\n");
writer.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writer.close();
}
}

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-07-04 14:59:26
* @LastEditTime: 2024-08-02 15:50:25
* @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.
@@ -21,15 +21,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import com.alibaba.fastjson2.JSON;
import com.bytedesk.ai.robot.RobotMessage;
import com.bytedesk.ai.robot.RobotProtobuf;
// import com.bytedesk.ai.robot.RobotResponseSimple;
import com.bytedesk.core.config.BytedeskEventPublisher;
import com.bytedesk.core.enums.ClientEnum;
import com.bytedesk.core.thread.Thread;
import com.bytedesk.core.message.Message;
import com.bytedesk.core.message.MessageProtobuf;
import com.bytedesk.core.message.MessageService;
import com.bytedesk.core.message.MessageStatusEnum;
import com.bytedesk.core.message.MessageTypeEnum;
@@ -38,8 +40,9 @@ import com.bytedesk.core.thread.ThreadService;
import com.bytedesk.core.uid.UidUtils;
import com.bytedesk.core.utils.JsonResult;
import com.bytedesk.core.utils.JsonResultCodeEnum;
import com.bytedesk.kbase.upload.UploadVectorStore;
import com.zhipu.oapi.ClientV4;
// import com.zhipu.oapi.Constants;
import com.zhipu.oapi.Constants;
import com.zhipu.oapi.service.v4.model.ChatCompletionRequest;
import com.zhipu.oapi.service.v4.model.ChatMessage;
import com.zhipu.oapi.service.v4.model.ChatMessageAccumulator;
@@ -61,7 +64,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@AllArgsConstructor
public class ZhipuAiService {
public class ZhipuaiService {
private final ClientV4 client;
@@ -73,6 +76,18 @@ public class ZhipuAiService {
private final MessageService messageService;
private final UploadVectorStore uploadVectorStore;
private final BytedeskEventPublisher bytedeskEventPublisher;
private final String PROMPT_BLUEPRINT = """
根据提供的文档信息回答问题,文档信息如下:
{context}
问题:
{query}
当用户提出的问题无法根据文档内容进行回复或者你也不清楚时,回复:未查找到相关问题答案.
""";
/**
* sse调用
*/
@@ -90,16 +105,14 @@ public class ZhipuAiService {
//
String messageUid = uidUtils.getCacheSerialUid();
Message message = Message.builder()
.type(MessageTypeEnum.ROBOT_QA)
.type(MessageTypeEnum.ROBOT)
.status(MessageStatusEnum.SUCCESS)
.client(ClientEnum.SYSTEM)
// .orgUid(thread.getOrgUid())
.user(JSON.toJSONString(user))
.build();
message.setUid(messageUid);
message.setOrgUid(thread.getOrgUid());
//
// message.getThreads().add(thread);
message.setThreadTopic(thread.getTopic());
if (!robotSimple.getLlm().isEnabled()) {
@@ -116,7 +129,6 @@ public class ZhipuAiService {
}
// 完成后完成SSE流
emitter.complete();
// TODO: 关键词匹配
return;
}
@@ -129,7 +141,7 @@ public class ZhipuAiService {
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
// 模型名称
// .model(Constants.ModelChatGLM3TURBO)
.model(robotSimple.getLlm().getModel().getValue())
.model(robotSimple.getLlm().getModel())
.temperature(robotSimple.getLlm().getTemperature())
.topP(robotSimple.getLlm().getTopP())
.stream(Boolean.TRUE)
@@ -188,7 +200,6 @@ public class ZhipuAiService {
data.setRequestId(chatCompletionRequest.getRequestId());
sseModelApiResp.setFlowable(null);// 打印前置空
sseModelApiResp.setData(data);
// 存储到数据库
robotMessage.setPromptTokens(chatMessageAccumulator.getUsage().getPromptTokens());
robotMessage.setCompletionTokens(chatMessageAccumulator.getUsage().getCompletionTokens());
@@ -208,6 +219,83 @@ public class ZhipuAiService {
log.info("sse output:" + result);
}
/**
* websocket 发送消息
*/
public void sendWsAutoReply(String query, String kbUid, MessageProtobuf messageProtobuf) {
//
List<String> contentList = uploadVectorStore.searchText(query, kbUid);
String context = String.join("\n", contentList);
String prompt = PROMPT_BLUEPRINT.replace("{context}", context).replace("{query}", query);
log.info("sendWsAutoReply prompt {}", prompt);
//
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), prompt);
messages.add(chatMessage);
//
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
// 模型名称
.model(Constants.ModelChatGLM3TURBO)
// .model(robotSimple.getLlm().getModel())
// .temperature(robotSimple.getLlm().getTemperature())
// .topP(robotSimple.getLlm().getTopP())
.stream(Boolean.TRUE)
.messages(messages)
.requestId(messageProtobuf.getUid())
.build();
//
ModelApiResponse sseModelApiResp = client.invokeModelApi(chatCompletionRequest);
if (sseModelApiResp.isSuccess()) {
AtomicBoolean isFirst = new AtomicBoolean(true);
List<Choice> choices = new ArrayList<>();
ChatMessageAccumulator chatMessageAccumulator = mapStreamToAccumulator(sseModelApiResp.getFlowable())
.doOnNext(accumulator -> {
{
if (isFirst.getAndSet(false)) {
log.info("answer start: ");
}
if (accumulator.getDelta() != null && accumulator.getDelta().getTool_calls() != null) {
String jsonString = JSON.toJSONString(accumulator.getDelta().getTool_calls());
log.info("tool_calls: " + jsonString);
}
if (accumulator.getDelta() != null && accumulator.getDelta().getContent() != null) {
String answerContent = accumulator.getDelta().getContent();
log.info("answerContent {}", answerContent);
if (StringUtils.hasText(answerContent)) {
messageProtobuf.setType(MessageTypeEnum.STREAM);
messageProtobuf.setContent(answerContent);
//
String json = JSON.toJSONString(messageProtobuf);
bytedeskEventPublisher.publishMessageJsonEvent(json);
}
}
}
})
.doOnComplete(() -> {
log.info("answer end");
})
.lastElement()
.blockingGet();
ModelData data = new ModelData();
data.setChoices(choices);
data.setUsage(chatMessageAccumulator.getUsage());
data.setId(chatMessageAccumulator.getId());
data.setCreated(chatMessageAccumulator.getCreated());
data.setRequestId(chatCompletionRequest.getRequestId());
sseModelApiResp.setFlowable(null);// 打印前置空
sseModelApiResp.setData(data);
// 存储到数据库
// robotMessage.setPromptTokens(chatMessageAccumulator.getUsage().getPromptTokens());
// robotMessage.setCompletionTokens(chatMessageAccumulator.getUsage().getCompletionTokens());
// robotMessage.setTotalTokens(chatMessageAccumulator.getUsage().getTotalTokens());
}
String result = JSON.toJSONString(sseModelApiResp);
log.info("websocket output:" + result);
}
public static Flowable<ChatMessageAccumulator> mapStreamToAccumulator(Flowable<ModelData> flowable) {
return flowable.map(chunk -> {
return new ChatMessageAccumulator(chunk.getChoices().get(0).getDelta(), null, chunk.getChoices().get(0),

BIN
modules/core/.DS_Store vendored

Binary file not shown.

View File

@@ -6,12 +6,12 @@
<parent>
<groupId>com.bytedesk</groupId>
<artifactId>modules</artifactId>
<version>${revision}</version>
<artifactId>modules</artifactId>
<version>${revision}</version>
</parent>
<artifactId>bytedesk-module-core</artifactId>
<name>bytedesk-module-core</name>
<description>Demo project for Spring Boot</description>
@@ -43,8 +43,6 @@
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
@@ -132,14 +130,6 @@
<scope>runtime</scope>
</dependency>
<!-- 导入、导出Excel -->
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.4</version>
</dependency>
<!-- 上传图片到阿里云OSS -->
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
@@ -177,7 +167,6 @@
<version>2.7.0</version>
</dependency>
</dependencies>
<build>

28
modules/core/readme.zh.md Normal file
View File

@@ -0,0 +1,28 @@
<!--
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:24:49
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-23 11:34: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.
-->
# 核心模块
```bash
```
## 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

@@ -1,94 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-08 23:49:59
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-09 10:41:34
* @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.Captcha;
// import java.util.Properties;
// import org.springframework.context.annotation.Bean;
// import org.springframework.context.annotation.Configuration;
// import com.google.code.kaptcha.impl.DefaultKaptcha;
// import com.google.code.kaptcha.util.Config;
// import static com.google.code.kaptcha.Constants.*;
// @Configuration
// public class CaptchaConfig {
// @Bean(name = "captchaProducer")
// public DefaultKaptcha getKaptchaBean() {
// DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// Properties properties = new Properties();
// // 是否有边框 默认为true 我们可以自己设置yesno
// properties.setProperty(KAPTCHA_BORDER, "yes");
// // 验证码文本字符颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// // 验证码图片宽度 默认为200
// properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// // 验证码图片高度 默认为50
// properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// // 验证码文本字符大小 默认为40
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// // KAPTCHA_SESSION_KEY
// properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// // 验证码文本字符长度 默认为5
// properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple
// // 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
// // 阴影com.google.code.kaptcha.impl.ShadowGimpy
// properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
// Config config = new Config(properties);
// defaultKaptcha.setConfig(config);
// return defaultKaptcha;
// }
// @Bean(name = "captchaProducerMath")
// public DefaultKaptcha getKaptchaBeanMath() {
// DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// Properties properties = new Properties();
// // 是否有边框 默认为true 我们可以自己设置yesno
// properties.setProperty(KAPTCHA_BORDER, "yes");
// // 边框颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
// // 验证码文本字符颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
// // 验证码图片宽度 默认为200
// properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// // 验证码图片高度 默认为50
// properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// // 验证码文本字符大小 默认为40
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
// // KAPTCHA_SESSION_KEY
// properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
// // 验证码文本生成器
// properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator");
// // 验证码文本字符间距 默认为2
// properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
// // 验证码文本字符长度 默认为5
// properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
// // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// // 验证码噪点颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
// // 干扰实现类
// properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
// // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple
// // 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
// // 阴影com.google.code.kaptcha.impl.ShadowGimpy
// properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
// Config config = new Config(properties);
// defaultKaptcha.setConfig(config);
// return defaultKaptcha;
// }
// }

View File

@@ -1,64 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-08 23:57:33
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-09 10:41:43
* @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.Captcha;
// import java.util.Random;
// import com.google.code.kaptcha.text.impl.DefaultTextCreator;
// public class KaptchaTextCreator extends DefaultTextCreator {
// private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
// @Override
// public String getText() {
// Integer result = 0;
// Random random = new Random();
// int x = random.nextInt(10);
// int y = random.nextInt(10);
// StringBuilder suChinese = new StringBuilder();
// int randomoperands = random.nextInt(3);
// if (randomoperands == 0) {
// result = x * y;
// suChinese.append(CNUMBERS[x]);
// suChinese.append("*");
// suChinese.append(CNUMBERS[y]);
// } else if (randomoperands == 1) {
// if ((x != 0) && y % x == 0) {
// result = y / x;
// suChinese.append(CNUMBERS[y]);
// suChinese.append("/");
// suChinese.append(CNUMBERS[x]);
// } else {
// result = x + y;
// suChinese.append(CNUMBERS[x]);
// suChinese.append("+");
// suChinese.append(CNUMBERS[y]);
// }
// } else {
// if (x >= y) {
// result = x - y;
// suChinese.append(CNUMBERS[x]);
// suChinese.append("-");
// suChinese.append(CNUMBERS[y]);
// } else {
// result = y - x;
// suChinese.append(CNUMBERS[y]);
// suChinese.append("-");
// suChinese.append(CNUMBERS[x]);
// }
// }
// suChinese.append("=?@" + result);
// return suChinese.toString();
// }
// }

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-17 16:53:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-04 12:53:51
* @LastEditTime: 2024-07-10 19:55:43
* @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.
@@ -37,5 +37,5 @@ public @interface ActionAnnotation {
public String description() default "";
public ActionTypeEnum type() default ActionTypeEnum.LOG; //TypeConsts.ACTION_TYPE_LOG;
public ActionTypeEnum type() default ActionTypeEnum.LOG;
}

View File

@@ -26,9 +26,9 @@ import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Service;
import com.bytedesk.core.base.BaseService;
import com.bytedesk.core.constant.BdConstants;
import com.bytedesk.core.rbac.auth.AuthService;
import com.bytedesk.core.rbac.user.User;
import com.bytedesk.core.rbac.user.UserConsts;
import com.bytedesk.core.uid.UidUtils;
import lombok.AllArgsConstructor;
@@ -55,14 +55,23 @@ public class ActionService extends BaseService<Action, ActionRequest, ActionResp
action.setUser(user);
action.setOrgUid(user.getOrgUid());
} else {
action.setOrgUid(UserConsts.DEFAULT_ORGANIZATION_UID);
action.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
}
Action savedAction = save(action);
if (savedAction == null) {
// TODO: handle exception
}
//
return convertToResponse(save(action));
return convertToResponse(savedAction);
}
public Action save(Action action) {
return actionRepository.save(action);
try {
return actionRepository.save(action);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public ActionResponse convertToResponse(Action action) {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-30 15:49:34
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:15:37
* @LastEditTime: 2024-07-09 21:42: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.

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-29 11:46:56
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-29 11:50:33
* @LastEditTime: 2024-07-24 14:11:53
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -15,24 +15,14 @@
package com.bytedesk.core.action;
public enum ActionTypeEnum {
LOG("log"),
FAILED("failed"),
VISITOR("visitor");
private final String value;
ActionTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
LOG,
FAILED,
VISITOR;
// 根据字符串查找对应的枚举常量
public static ActionTypeEnum fromValue(String value) {
for (ActionTypeEnum type : ActionTypeEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}

View File

@@ -0,0 +1,25 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 12:15:46
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:24:39
* @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.action.disruptor;
import lombok.Data;
// https://lmax-exchange.github.io/disruptor/user-guide/#_getting_started
@Data
public class LogEvent {
private String content;
}

View File

@@ -0,0 +1,47 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 13:20:50
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:32:59
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.action.disruptor;
import java.util.concurrent.Executors;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
@Configuration
public class LogEventConfig {
@Bean
public RingBuffer<LogEvent> logEventRingBuffer() {
// 消费者线程池
// ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("weiyuai-pool-%d").build();
// 事件工厂
LogEventFactory eventFactory = new LogEventFactory();
// 指定RingBuffer大小
int bufferSize = 1024;
// 构造事件分发器
Disruptor<LogEvent> disruptor = new Disruptor<LogEvent>(eventFactory, bufferSize,
Executors.defaultThreadFactory());
// 注册消费者
disruptor.handleEventsWith(new LogEventHandler());
// 启动事件分发
disruptor.start();
// 获取RingBuffer 用于生产事件
RingBuffer<LogEvent> ringBuffer = disruptor.getRingBuffer();
//
return ringBuffer;
}
}

View File

@@ -0,0 +1,24 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 12:32:51
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:29: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.action.disruptor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1")
public class LogEventController {
}

View File

@@ -0,0 +1,27 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 12:16:51
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:29: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.action.disruptor;
import com.lmax.disruptor.EventFactory;
// https://lmax-exchange.github.io/disruptor/user-guide/#_getting_started
public class LogEventFactory implements EventFactory<LogEvent> {
@Override
public LogEvent newInstance() {
return new LogEvent();
}
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-08 12:13:12
* @Date: 2024-07-17 12:17:42
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-08 12:13:31
* @LastEditTime: 2024-07-17 14:22: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.
@@ -12,36 +12,19 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.utils.id;
package com.bytedesk.core.action.disruptor;
/**
* ID生成器的配置接口
* @author Ivan.Ma
*/
public interface IdGeneratorConfig {
import com.lmax.disruptor.EventHandler;
/**
* 获取分隔符
* @return string
*/
String getSplitString();
import lombok.extern.slf4j.Slf4j;
/**
* 获取初始值
* @return int
*/
int getInitial();
// https://lmax-exchange.github.io/disruptor/user-guide/#_getting_started
@Slf4j
public class LogEventHandler implements EventHandler<LogEvent> {
/**
* 获取ID前缀
* @return string
*/
String getPrefix();
/**
* 获取滚动间隔, 单位:
* @return int
*/
int getRollingInterval();
@Override
public void onEvent(LogEvent event, long sequence, boolean endOfBatch) throws Exception {
log.info("Disruptor LongEventHandler: {}, sequence {}, endOfBatch {}", event.getContent(), sequence, endOfBatch);
}
}

View File

@@ -0,0 +1,45 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 12:31:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:40:01
* @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.action.disruptor;
import org.springframework.stereotype.Component;
import com.lmax.disruptor.RingBuffer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@RequiredArgsConstructor
public class LogEventProducer {
private final RingBuffer<LogEvent> ringBuffer;
public void simulate() {
log.info("simulate producer");
// 模拟日志生成
for (int i = 0; i < 10000; i++) {
long sequence = ringBuffer.next();
try {
LogEvent event = ringBuffer.get(sequence);
event.setContent("Log Message " + i); // 模拟日志消息
} finally {
ringBuffer.publish(sequence);
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 12:33:14
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 16:32:09
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.action.disruptor;
import org.springframework.stereotype.Service;
import com.lmax.disruptor.RingBuffer;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@AllArgsConstructor
public class LogEventService {
private final RingBuffer<LogEvent> logEventRingBuffer;
public void testMq(String content) {
log.info("record the content: {}", content);
// 获取下一个Event槽的下标
long sequence = logEventRingBuffer.next();
try {
// 给Event填充数据
LogEvent event = logEventRingBuffer.get(sequence);
event.setContent(content);
log.info("add event to mq: {}", event);
} catch (Exception e) {
log.error("failed to add event to longEventRingBuffer for : e = {},{}", e, e.getMessage());
} finally {
// 发布Event激活观察者去消费将sequence传递给改消费者
// 注意最后的publish方法必须放在finally中以确保必须得到调用如果某个请求的sequence未被提交将会堵塞后续的发布操作或者其他的producer
logEventRingBuffer.publish(sequence);
}
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 20:32:23
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:15:12
* @LastEditTime: 2024-08-04 12:13:14
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -14,7 +14,7 @@
*/
package com.bytedesk.core.asistant;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.base.BaseEntityNoOrg;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;
@@ -40,9 +40,8 @@ import lombok.experimental.Accessors;
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners({ AsistantEntityListener.class })
// @DiscriminatorValue("Asistant")
@Table(name = "core_asistant")
public class Asistant extends BaseEntity {
public class Asistant extends BaseEntityNoOrg {
private static final long serialVersionUID = 1L;
@@ -59,6 +58,4 @@ public class Asistant extends BaseEntity {
@Builder.Default
private String description = I18Consts.I18N_USER_DESCRIPTION;
/** belong to org */
// private String orgUid;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-20 14:31:54
* @Date: 2024-08-04 11:32:22
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-20 14:31:57
* @LastEditTime: 2024-08-04 11:53: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.
@@ -12,14 +12,14 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.quick_reply;
package com.bytedesk.core.asistant;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.bytedesk.core.rbac.organization.Organization;
import com.bytedesk.core.rbac.organization.OrganizationCreateEvent;
import com.bytedesk.core.rbac.user.User;
import com.bytedesk.core.rbac.user.UserCreateEvent;
import com.bytedesk.core.thread.ThreadService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -27,15 +27,18 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@AllArgsConstructor
public class QuickReplyEventListener {
@Order(7)
public class AsistantEventListener {
private final ThreadService threadService;
@EventListener
public void onOrganizationCreateEvent(OrganizationCreateEvent event) {
Organization organization = (Organization) event.getSource();
// User user = organization.getUser();
log.info("quick_reply - organization created: {}", organization.getName());
public void onUserCreateEvent(UserCreateEvent event) {
User user = event.getUser();
log.info("asistant onUserCreateEvent: {}", user.getUid());
//
// 每创建一个用户自动给此用户生成一条文件助理的会话
threadService.createFileAsistantThread(user);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 21:05:09
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 10:05:18
* @LastEditTime: 2024-08-04 12:14:23
* @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,7 +14,7 @@
*/
package com.bytedesk.core.asistant;
import com.bytedesk.core.base.BaseRequest;
import com.bytedesk.core.base.BaseRequestNoOrg;
import lombok.Builder;
import lombok.Data;
@@ -25,10 +25,8 @@ import lombok.experimental.Accessors;
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class AsistantRequest extends BaseRequest {
public class AsistantRequest extends BaseRequestNoOrg {
// private String aid;
private String topic;
private String nickname;
@@ -36,7 +34,4 @@ public class AsistantRequest extends BaseRequest {
private String avatar;
private String description;
/** belong to org */
// private String orgUid;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 21:04:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-29 16:44:40
* @LastEditTime: 2024-08-04 12:16:49
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -25,7 +25,7 @@ import org.springframework.util.StringUtils;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.rbac.user.UserConsts;
import com.bytedesk.core.constant.BdConstants;
import com.bytedesk.core.topic.TopicUtils;
import com.bytedesk.core.uid.UidUtils;
@@ -34,25 +34,22 @@ import lombok.AllArgsConstructor;
@Service
@AllArgsConstructor
public class AsistantService {
private final AsistantRepository asistantRepository;
// private final UserService userService;
// private final ThreadService threadService;
private final ModelMapper modelMapper;
private final UidUtils uidUtils;
public Page<AsistantResponse> query(AsistantRequest asistantRequest) {
Pageable pageable = PageRequest.of(asistantRequest.getPageNumber(), asistantRequest.getPageSize(), Sort.Direction.ASC,
Pageable pageable = PageRequest.of(asistantRequest.getPageNumber(), asistantRequest.getPageSize(),
Sort.Direction.ASC,
"id");
Page<Asistant> asistantPage = asistantRepository.findAll(pageable);
return asistantPage.map(asistant -> convertToAsistantResponse(asistant));
return asistantPage.map(asistant -> convertToResponse(asistant));
}
public Asistant create(AsistantRequest asistantRequest) {
@@ -61,21 +58,21 @@ public class AsistantService {
if (!StringUtils.hasText(asistant.getUid())) {
asistant.setUid(uidUtils.getCacheSerialUid());
}
return save(asistant);
}
private Asistant save(Asistant asistant) {
return asistantRepository.save(asistant);
}
public AsistantResponse convertToAsistantResponse(Asistant asistant) {
public AsistantResponse convertToResponse(Asistant asistant) {
return modelMapper.map(asistant, AsistantResponse.class);
}
//
//
public void initData() {
if (asistantRepository.count() > 0) {
return;
}
@@ -86,13 +83,10 @@ public class AsistantService {
.avatar(AvatarConsts.DEFAULT_FILE_ASISTANT_AVATAR_URL)
.description(I18Consts.I18N_FILE_ASISTANT_DESCRIPTION)
.build();
asistantRequest.setUid(UserConsts.DEFAULT_FILE_ASISTANT_UID);
asistantRequest.setUid(BdConstants.DEFAULT_FILE_ASISTANT_UID);
asistantRequest.setType(TypeConsts.TYPE_SYSTEM);
asistantRequest.setOrgUid(UserConsts.DEFAULT_ORGANIZATION_UID);
// asistantRequest.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
create(asistantRequest);
}
}

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-23 11:10:49
* @LastEditTime: 2024-07-23 14:02:40
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesa
* 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.
@@ -69,6 +69,8 @@ public abstract class BaseEntity implements Serializable {
@Version
private int version;
// 在配置文件中存储时区信息TODO: 应用层处理时区转换?
// 数据库DDL中 created_at timestamp(6) without time zone,
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", updatable = false)
@CreatedDate
@@ -79,12 +81,9 @@ public abstract class BaseEntity implements Serializable {
@LastModifiedDate
private Date updatedAt;
/**
* soft delete
*/
// soft delete
@Column(name = "is_deleted")
private boolean deleted = false;
//
private String orgUid;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 17:00:31
* @Date: 2024-01-29 16:21:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-04 10:55:22
* @LastEditTime: 2024-08-04 12:14: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.
@@ -12,23 +12,26 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.doc;
package com.bytedesk.core.base;
import com.bytedesk.core.base.BaseRequest;
import java.io.Serializable;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class KbDocRequest extends BaseRequest {
public abstract class BaseRequestNoOrg implements Serializable {
// private String did;
private String meta;
public String uid;
public int pageNumber;
public int pageSize;
public String type;
public String content;
public String client;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-22 16:11:42
* @Date: 2024-03-28 22:02:34
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-02 17:40:05
* @LastEditTime: 2024-08-01 07:01:34
* @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,10 +12,10 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.leave_msg;
package com.bytedesk.core.black;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.thread.Thread;
import com.bytedesk.core.rbac.user.User;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Entity;
@@ -29,7 +29,8 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 留言
* black list
* 黑名单
*/
@Entity
@Data
@@ -38,20 +39,14 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "service_leave_message")
public class LeaveMessage extends BaseEntity {
@Table(name = "core_black")
public class Black extends BaseEntity {
private static final long serialVersionUID = 1L;
//
private String reason;
// 联系方式
private String contact;
// 留言内容
private String content;
@JsonIgnore
@ManyToOne
// private Visitor visitor;
private Thread thread;
@JsonIgnore
@ManyToOne
private User user;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:46:14
* @Date: 2024-06-27 12:20:45
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-09 10:49:01
* @LastEditTime: 2024-08-01 19:43:10
* @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,56 +12,46 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.kb;
package com.bytedesk.core.black;
import org.springframework.http.ResponseEntity;
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.base.BaseController;
import lombok.AllArgsConstructor;
/**
*
*/
@RestController
@RequestMapping("/api/v1/kb")
@AllArgsConstructor
public class KbController extends BaseController<KbRequest> {
// private final KbService kbService;
@RequestMapping("/api/v1/black")
public class BlackController extends BaseController<BlackRequest> {
@Override
public ResponseEntity<?> queryByOrg(KbRequest request) {
public ResponseEntity<?> queryByOrg(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'queryByOrg'");
}
@Override
public ResponseEntity<?> query(KbRequest request) {
public ResponseEntity<?> query(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'query'");
}
@Override
public ResponseEntity<?> create(@RequestBody KbRequest request) {
public ResponseEntity<?> create(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'create'");
}
@Override
public ResponseEntity<?> update(@RequestBody KbRequest request) {
public ResponseEntity<?> update(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'update'");
}
@Override
public ResponseEntity<?> delete(@RequestBody KbRequest request) {
public ResponseEntity<?> delete(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'delete'");
}
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-28 22:04:02
* @Date: 2024-08-01 07:01:58
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-03-28 22:04:05
* @LastEditTime: 2024-08-01 07:02:01
* @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,11 +12,11 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.status;
package com.bytedesk.core.black;
/**
* 接待状态切换记录
*/
public class Status {
import org.springframework.stereotype.Component;
@Component
public class BlackEntityListener {
}

View File

@@ -0,0 +1,22 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-27 12:21:09
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-27 12:21: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.black;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface BlackRepository extends JpaRepository<Black, String>, JpaSpecificationExecutor<Black> {
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-22 16:19:18
* @Date: 2024-06-27 12:21:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-02-22 16:48:26
* @LastEditTime: 2024-06-27 12:23: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.
@@ -12,11 +12,10 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.status;
package com.bytedesk.core.black;
/**
* 状态变更记录
*/
public class Status {
import com.bytedesk.core.base.BaseRequest;
public class BlackRequest extends BaseRequest {
}

View File

@@ -0,0 +1,21 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-27 12:21:29
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-27 12:21: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.black;
import com.bytedesk.core.base.BaseResponse;
public class BlackResponse extends BaseResponse {
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 17:00:07
* @Date: 2024-06-27 12:20:55
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-05-27 11:55:19
* @LastEditTime: 2024-08-01 19:42:05
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.doc;
package com.bytedesk.core.black;
import java.util.Optional;
@@ -26,44 +26,40 @@ import lombok.AllArgsConstructor;
@Service
@AllArgsConstructor
public class KbDocService extends BaseService<KbDoc, KbDocRequest, KbDocResponse> {
// private final KbDocRepository kbDocRepository;
// private final ModelMapper modelMapper;
public class BlackService extends BaseService<Black, BlackRequest, BlackResponse> {
@Override
public Page<KbDocResponse> queryByOrg(KbDocRequest request) {
public Page<BlackResponse> queryByOrg(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'queryByOrg'");
}
@Override
public Page<KbDocResponse> queryByUser(KbDocRequest request) {
public Page<BlackResponse> queryByUser(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'queryByUser'");
}
@Override
public Optional<KbDoc> findByUid(String uid) {
public Optional<Black> findByUid(String uid) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByUid'");
}
@Override
public KbDocResponse create(KbDocRequest request) {
public BlackResponse create(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'create'");
}
@Override
public KbDocResponse update(KbDocRequest request) {
public BlackResponse update(BlackRequest request) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'update'");
}
@Override
public KbDoc save(KbDoc entity) {
public Black save(Black entity) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'save'");
}
@@ -75,37 +71,21 @@ public class KbDocService extends BaseService<KbDoc, KbDocRequest, KbDocResponse
}
@Override
public void delete(KbDoc entity) {
public void delete(Black entity) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'delete'");
}
@Override
public void handleOptimisticLockingFailureException(ObjectOptimisticLockingFailureException e, KbDoc entity) {
public void handleOptimisticLockingFailureException(ObjectOptimisticLockingFailureException e, Black entity) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'handleOptimisticLockingFailureException'");
}
@Override
public KbDocResponse convertToResponse(KbDoc entity) {
public BlackResponse convertToResponse(Black entity) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'convertToResponse'");
}
// public Page<KbDocResponse> query(KbDocRequest kbDocRequest) {
// Pageable pageable = PageRequest.of(kbDocRequest.getPageNumber(), kbDocRequest.getPageSize(),
// Sort.Direction.DESC,
// "id");
// Page<KbDoc> kbDocPage = kbDocRepository.findAll(pageable);
// return kbDocPage.map(this::convertToDocResponse);
// }
// public KbDocResponse convertToDocResponse(KbDoc kbDoc) {
// return modelMapper.map(kbDoc, KbDocResponse.class);
// }
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-30 20:46:30
* @Date: 2024-06-27 12:21:44
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-30 20:46:32
* @LastEditTime: 2024-06-27 12:24:15
* @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,10 +12,10 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.ticket;
package com.bytedesk.core.black;
import com.bytedesk.core.base.BaseSpecification;
public class TicketSpecification extends BaseSpecification {
public class BlackSpecification extends BaseSpecification {
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-03 18:13:55
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 11:11:15
* @LastEditTime: 2024-07-24 21:26: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.
@@ -51,14 +51,11 @@ public class Category extends BaseEntity {
private String name;
// private String description;
// this category type may be user defined, so it should use string type, not enum
@Column(name = "category_type", nullable = false)
private String type;
private String icon;
// private String icon;
// @Column(unique = true)
// private String path;
@@ -83,8 +80,8 @@ public class Category extends BaseEntity {
@Builder.Default
private PlatformEnum platform = PlatformEnum.BYTEDESK;
/** belong to org */
// private String orgUid;
// knowledge base uid
private String kbUid;
public void addChild(Category child) {
children.add(child);

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-11 18:21:44
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 10:06:10
* @LastEditTime: 2024-07-24 21:27: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.
@@ -38,8 +38,7 @@ import lombok.experimental.Accessors;
public class CategoryRequest extends BaseRequest {
private String name;
private String icon;
// private String icon;
@Builder.Default
private Integer orderNo = 0;
@@ -51,11 +50,10 @@ public class CategoryRequest extends BaseRequest {
@NotBlank
@Builder.Default
private String platform = BdConstants.PLATFORM_BYTEDESK;
// private PlatformEnum platform = PlatformEnum.BYTEDESK;
@Builder.Default
private List<String> children = new ArrayList<>();
/** belong to org */
// private String orgUid;
// knowledge base uid
private String kbUid;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-11 18:21:53
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 16:54:49
* @LastEditTime: 2024-07-24 20:35:19
* @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.
@@ -35,9 +35,12 @@ public class CategoryResponse extends BaseResponse {
private String type;
private String icon;
// private String icon;
private Integer orderNo;
// private List<CategoryResponse> children;
// knowledge base uid
private String kbUid;
}

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-24 09:36:10
* @LastEditTime: 2024-07-24 20:43: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.
@@ -34,7 +34,6 @@ import com.bytedesk.core.constant.BdConstants;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LevelEnum;
import com.bytedesk.core.enums.PlatformEnum;
import com.bytedesk.core.rbac.user.UserConsts;
import com.bytedesk.core.uid.UidUtils;
import lombok.AllArgsConstructor;
@@ -114,7 +113,7 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
PlatformEnum platform) {
return categoryRepository.findByNameAndTypeAndOrgUidAndPlatform(name, type, orgUid, platform);
}
public Optional<Category> findByNameAndTypeAndLevelAndPlatform(String name, String type, LevelEnum level,
PlatformEnum platform) {
return categoryRepository.findByNameAndTypeAndLevelAndPlatform(name, type, level, platform);
@@ -130,7 +129,7 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
Category entity = category.get();
// modelMapper.map(request, entity);
entity.setName(request.getName());
entity.setIcon(request.getIcon());
// entity.setIcon(request.getIcon());
entity.setType(request.getType());
// entity.setPlatform(request.getPlatform());
@@ -178,7 +177,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;
}
@@ -187,21 +187,24 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
return list.stream().map(city -> convertToResponse(city)).collect(Collectors.toList());
}
//
//
public void initData() {
if (categoryRepository.count() > 0) {
return;
}
//
// level = platform, 不需要设置orgUid
// init quick reply categories
CategoryRequest categoryContact = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_CONTACT)
.orderNo(0)
.level(LevelEnum.PLATFORM)
.platform(BdConstants.PLATFORM_BYTEDESK)
// .orgUid(orgUid)
.build();
categoryContact.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
// categoryContact.setOrgUid(orgUid);
create(categoryContact);
CategoryRequest categoryThanks = CategoryRequest.builder()
@@ -209,39 +212,38 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
.orderNo(1)
.level(LevelEnum.PLATFORM)
.platform(BdConstants.PLATFORM_BYTEDESK)
// .orgUid(orgUid)
.build();
categoryThanks.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
// categoryThanks.setOrgUid(orgUid);
create(categoryThanks);
CategoryRequest categoryWelcome = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_WELCOME)
.orderNo(2)
// .orgUid(orgUid)
.level(LevelEnum.PLATFORM)
.platform(BdConstants.PLATFORM_BYTEDESK)
.build();
categoryWelcome.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
// categoryWelcome.setOrgUid(orgUid);
create(categoryWelcome);
CategoryRequest categoryBye = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_BYE)
.orderNo(3)
// .orgUid(orgUid)
.level(LevelEnum.PLATFORM)
.platform(BdConstants.PLATFORM_BYTEDESK)
.build();
categoryBye.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
// categoryBye.setOrgUid(orgUid);
create(categoryBye);
//
String orgUid = UserConsts.DEFAULT_ORGANIZATION_UID;
//
String orgUid = BdConstants.DEFAULT_ORGANIZATION_UID;
CategoryRequest categoryFaqDemoRequest1 = CategoryRequest.builder()
.name(I18Consts.I18N_FAQ_CATEGORY_DEMO_1)
.orderNo(0)
.level(LevelEnum.ORGNIZATION)
.platform(BdConstants.PLATFORM_BYTEDESK)
// .orgUid(orgUid)
.build();
categoryFaqDemoRequest1.setType(CategoryConsts.CATEGORY_TYPE_FAQ);
categoryFaqDemoRequest1.setUid(orgUid + I18Consts.I18N_FAQ_CATEGORY_DEMO_1);
@@ -253,13 +255,11 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
.orderNo(0)
.level(LevelEnum.ORGNIZATION)
.platform(BdConstants.PLATFORM_BYTEDESK)
// .orgUid(orgUid)
.build();
categoryFaqDemoRequest2.setType(CategoryConsts.CATEGORY_TYPE_FAQ);
categoryFaqDemoRequest2.setUid(orgUid + I18Consts.I18N_FAQ_CATEGORY_DEMO_2);
categoryFaqDemoRequest1.setOrgUid(orgUid);
categoryFaqDemoRequest2.setOrgUid(orgUid);
create(categoryFaqDemoRequest2);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-08 12:49:00
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 12:50:11
* @LastEditTime: 2024-07-25 15:08: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.
@@ -40,6 +40,9 @@ public class CategorySpecification extends BaseSpecification {
if (StringUtils.hasText(request.getType())) {
predicates.add(criteriaBuilder.like(root.get("type"), "%" + request.getType() + "%"));
}
if (StringUtils.hasText(request.getKbUid())) {
predicates.add(criteriaBuilder.equal(root.get("kbUid"), request.getKbUid()));
}
//
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 20:34:52
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-29 16:47:36
* @LastEditTime: 2024-08-04 12:13: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.
@@ -14,7 +14,7 @@
*/
package com.bytedesk.core.channel;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.base.BaseEntityNoOrg;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;
@@ -40,9 +40,8 @@ import lombok.experimental.Accessors;
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners({ ChannelEntityListener.class })
// @DiscriminatorValue("Channel")
@Table(name = "core_channel")
public class Channel extends BaseEntity {
public class Channel extends BaseEntityNoOrg {
private static final long serialVersionUID = 1L;

View File

@@ -0,0 +1,43 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-08-04 11:32:45
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-04 11:54:21
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.channel;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import com.bytedesk.core.rbac.user.User;
import com.bytedesk.core.rbac.user.UserCreateEvent;
import com.bytedesk.core.thread.ThreadService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@AllArgsConstructor
public class ChannelEventListener {
private final ThreadService threadService;
@EventListener
public void onUserCreateEvent(UserCreateEvent event) {
User user = event.getUser();
log.info("channel onUserCreateEvent: {}", user.getUid());
//
// 每创建一个用户,自动给此用户生成一条系统通知的会话
threadService.createSystemChannelThread(user);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 21:07:10
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-23 10:06:43
* @LastEditTime: 2024-08-04 12:15:23
* @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,7 +14,7 @@
*/
package com.bytedesk.core.channel;
import com.bytedesk.core.base.BaseRequest;
import com.bytedesk.core.base.BaseRequestNoOrg;
import lombok.Builder;
import lombok.Data;
@@ -25,10 +25,8 @@ import lombok.experimental.Accessors;
@Builder
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class ChannelRequest extends BaseRequest {
public class ChannelRequest extends BaseRequestNoOrg {
// private String cid;
private String topic;
private String nickname;
@@ -36,7 +34,4 @@ public class ChannelRequest extends BaseRequest {
private String avatar;
private String description;
/** belong to org */
// private String orgUid;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 21:06:12
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-29 16:46:59
* @LastEditTime: 2024-08-04 12: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.
@@ -24,7 +24,6 @@ import org.springframework.stereotype.Service;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.rbac.user.UserConsts;
import com.bytedesk.core.topic.TopicUtils;
import com.bytedesk.core.uid.UidUtils;
@@ -36,22 +35,21 @@ public class ChannelService {
private final ChannelRepository channelRepository;
// private final UserService userService;
private final ModelMapper modelMapper;
private final UidUtils uidUtils;
public Page<ChannelResponse> query(ChannelRequest channelRequest) {
Pageable pageable = PageRequest.of(channelRequest.getPageNumber(), channelRequest.getPageSize(), Sort.Direction.ASC,
Pageable pageable = PageRequest.of(channelRequest.getPageNumber(), channelRequest.getPageSize(),
Sort.Direction.ASC,
"id");
Page<Channel> channelPage = channelRepository.findAll(pageable);
return channelPage.map(channel -> convertToChannelResponse(channel));
return channelPage.map(channel -> convertToResponse(channel));
}
public Channel create(ChannelRequest channelRequest) {
Channel channel = modelMapper.map(channelRequest, Channel.class);
@@ -64,16 +62,16 @@ public class ChannelService {
return channelRepository.save(channel);
}
public ChannelResponse convertToChannelResponse(Channel channel) {
public ChannelResponse convertToResponse(Channel channel) {
return modelMapper.map(channel, ChannelResponse.class);
}
public void initData() {
if (channelRepository.count() > 0) {
return;
}
ChannelRequest channelRequest = ChannelRequest.builder()
.topic(TopicUtils.TOPIC_SYSTEM_NOTIFICATION)
.nickname(I18Consts.I18N_SYSTEM_NOTIFICATION_NAME)
@@ -81,9 +79,8 @@ public class ChannelService {
.description(I18Consts.I18N_SYSTEM_NOTIFICATION_DESCRIPTION)
.build();
channelRequest.setType(TypeConsts.TYPE_SYSTEM);
channelRequest.setOrgUid(UserConsts.DEFAULT_ORGANIZATION_UID);
// channelRequest.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
create(channelRequest);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-30 07:52:26
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-22 23:32:51
* @LastEditTime: 2024-07-30 09:11:25
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -17,6 +17,7 @@ package com.bytedesk.core.config;
import java.nio.charset.StandardCharsets;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@@ -28,6 +29,8 @@ import org.springframework.web.client.RestTemplate;
import com.bytedesk.core.utils.ApplicationContextHolder;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import lombok.Getter;
/**
@@ -37,6 +40,9 @@ import lombok.Getter;
@Configuration
public class BytedeskConfig {
@Value("${application.version}")
private String appVersion;
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
@@ -52,7 +58,6 @@ public class BytedeskConfig {
return config.getAuthenticationManager();
}
// @SuppressWarnings("null")
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); //
@@ -65,4 +70,17 @@ public class BytedeskConfig {
return new ApplicationContextHolder();
}
@Bean
public OpenAPI apiInfo() {
return new OpenAPI().info(new Info().title("bytedesk apis").version(appVersion));
}
// @Bean
// public GroupedOpenApi httpApi() {
// return GroupedOpenApi.builder()
// .group("http")
// .pathsToMatch("/**")
// .build();
// }
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-23 14:42:58
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-04 10:45:20
* @LastEditTime: 2024-07-28 07:28:29
* @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.
@@ -21,7 +21,8 @@ import org.springframework.stereotype.Component;
import com.bytedesk.core.action.ActionEvent;
import com.bytedesk.core.action.ActionRequest;
import com.bytedesk.core.cache.CaffeineCacheGroupEvent;
import com.bytedesk.core.event.GenericApplicationEvent;
// import com.bytedesk.core.cache.CaffeineCacheGroupEvent;
import com.bytedesk.core.message.MessageProtoEvent;
import com.bytedesk.core.message.MessageUpdateEvent;
import com.bytedesk.core.message.Message;
@@ -33,14 +34,14 @@ import com.bytedesk.core.rbac.organization.OrganizationCreateEvent;
import com.bytedesk.core.rbac.user.User;
import com.bytedesk.core.rbac.user.UserCreateEvent;
import com.bytedesk.core.rbac.user.UserUpdateEvent;
import com.bytedesk.core.socket.mqtt.event.MqttConnectedEvent;
import com.bytedesk.core.socket.mqtt.event.MqttDisconnectedEvent;
import com.bytedesk.core.socket.mqtt.event.MqttSubscribeEvent;
import com.bytedesk.core.socket.mqtt.event.MqttUnsubscribeEvent;
import com.bytedesk.core.socket.stomp.event.StompConnectedEvent;
import com.bytedesk.core.socket.stomp.event.StompDisconnectedEvent;
import com.bytedesk.core.socket.stomp.event.StompSubscribeEvent;
import com.bytedesk.core.socket.stomp.event.StompUnsubscribeEvent;
import com.bytedesk.core.socket.mqtt.MqttConnectedEvent;
import com.bytedesk.core.socket.mqtt.MqttDisconnectedEvent;
import com.bytedesk.core.socket.mqtt.MqttSubscribeEvent;
import com.bytedesk.core.socket.mqtt.MqttUnsubscribeEvent;
import com.bytedesk.core.socket.stomp.StompConnectedEvent;
import com.bytedesk.core.socket.stomp.StompDisconnectedEvent;
import com.bytedesk.core.socket.stomp.StompSubscribeEvent;
import com.bytedesk.core.socket.stomp.StompUnsubscribeEvent;
import com.bytedesk.core.thread.Thread;
import com.bytedesk.core.thread.ThreadCreateEvent;
import com.bytedesk.core.thread.ThreadUpdateEvent;
@@ -56,6 +57,10 @@ public class BytedeskEventPublisher {
private final ApplicationEventPublisher applicationEventPublisher;
public void publishGenericApplicationEvent(GenericApplicationEvent<?> event) {
applicationEventPublisher.publishEvent(event);
}
public void publishTopicCreateEvent(String topic, String userUid) {
applicationEventPublisher.publishEvent(new TopicCreateEvent(this, topic, userUid));
}
@@ -144,8 +149,8 @@ public class BytedeskEventPublisher {
// applicationEventPublisher.publishEvent(new EmailAlreadyExistsEvent(this, email));
// }
public void publishCaffeineCacheGroupEvent(String groupUid, String messageJson) {
applicationEventPublisher.publishEvent(new CaffeineCacheGroupEvent(this, groupUid, messageJson));
}
// public void publishCaffeineCacheGroupEvent(String groupUid, String messageJson) {
// applicationEventPublisher.publishEvent(new CaffeineCacheGroupEvent(this, groupUid, messageJson));
// }
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-30 09:14:39
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-03 12:08:11
* @LastEditTime: 2024-07-28 17:00: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.
@@ -24,12 +24,12 @@ import lombok.Data;
@Data
@Component
@ConfigurationProperties(prefix = "bytedesk")
@ConfigurationProperties(BytedeskProperties.CONFIG_PREFIX)
public class BytedeskProperties {
private Boolean debug;
public static final String CONFIG_PREFIX = "bytedesk";
// private String username;
private Boolean debug;
private String email;
@@ -56,7 +56,6 @@ public class BytedeskProperties {
// jwt
private String jwtSecretKey;
private String jwtExpiration;
// cache

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-27 18:45:02
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-15 15:23:56
* @LastEditTime: 2024-07-17 12:08:23
* @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.core.cache;
package com.bytedesk.core.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
@@ -27,4 +27,16 @@ import org.springframework.context.annotation.Configuration;
@EnableCaching
public class CacheConfig {
// @Bean
// public Caffeine<Object, Object> caffeineConfig() {
// return Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.SECONDS);
// }
// @Bean
// public CacheManager cacheManager(Caffeine<Object, Object> caffeine) {
// CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
// caffeineCacheManager.setCaffeine(caffeine);
// return caffeineCacheManager;
// }
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-19 11:39:40
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-19 16:20:13
* @LastEditTime: 2024-07-29 17:10: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.
@@ -31,7 +31,7 @@ public class CorsConfig {
* 经测试仅有此处起作用corsFilter()和WebMvcConfig.addCorsMappings()不起作用
* @return
*/
// https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html
// https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
@@ -48,22 +48,23 @@ public class CorsConfig {
return source;
}
// @Bean
// public CorsFilter corsFilter() {
// log.info("CorsConfig.corsFilter()");
// CorsConfiguration corsConfiguration = new CorsConfiguration();
// //1,允许任何来源
// corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
// //2,允许任何请求头
// corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
// //3,允许任何方法
// corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
// //4,允许凭证
// corsConfiguration.setAllowCredentials(true);
// //
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", corsConfiguration);
// //
// return new CorsFilter(source);
// }
// @Bean
// public CorsFilter corsFilter() {
// log.info("CorsConfig.corsFilter()");
// CorsConfiguration corsConfiguration = new CorsConfiguration();
// //1,允许任何来源
// corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
// //2,允许任何请求头
// corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
// //3,允许任何方法
// corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
// //4,允许凭证
// corsConfiguration.setAllowCredentials(true);
// //
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", corsConfiguration);
// //
// return new CorsFilter(source);
// }
}

View File

@@ -0,0 +1,51 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-23 08:12:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-28 17:01:21
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.config;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;
// import lombok.EqualsAndHashCode;
import redis.clients.jedis.Protocol;
@Data
// @EqualsAndHashCode(callSuper=false)
@Component
@ConfigurationProperties(JedisProperties.CONFIG_PREFIX)
public class JedisProperties {
// extends JedisPoolConfig
public static final String CONFIG_PREFIX = "spring.data.redis";
private String host;
private int port;
private String password;
private int database;
//
private int timeout;
private int soTimeout = Protocol.DEFAULT_TIMEOUT;
private String clientName;
private boolean ssl;
// private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
}

View File

@@ -0,0 +1,48 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-29 12:01:27
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-29 12:10: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
// https://docs.spring.io/spring-data/redis/reference/redis/getting-started.html
@Configuration
public class RedisConfig {
@Autowired
private JedisProperties jedisProperties;
// https://docs.spring.io/spring-data/redis/reference/redis/connection-modes.html
@Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(
jedisProperties.getHost(), jedisProperties.getPort());
redisStandaloneConfiguration.setPassword(jedisProperties.getPassword());
redisStandaloneConfiguration.setDatabase(jedisProperties.getDatabase());
//
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-26 15:28:57
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-18 21:44:08
* @LastEditTime: 2024-07-29 16:56:27
* @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,12 +32,6 @@ import com.bytedesk.core.ip.IpInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// @Autowired
// private UploadStorageProperties uploadStorageProperties;
// @Autowired
// private BytedeskProperties bytedeskProperties;
// https://www.baeldung.com/spring-mvc-static-resources
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/",

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-28 11:10:14
* @LastEditTime: 2024-08-03 13:13:27
* @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.
@@ -31,103 +31,103 @@ public class AvatarConsts {
* default avatar
* 默认注册用户头像URL
*/
public static final String DEFAULT_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/admin_default_avatar.png";
public static final String DEFAULT_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/admin_default_avatar.png";
/**
* default agent avatar
* 默认客服头像
*/
public static final String DEFAULT_AGENT_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/agent_default_avatar.png";
public static final String DEFAULT_AGENT_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/agent_default_avatar.png";
/**
* default visitor avatar
* 默认访客头像
*/
public static final String DEFAULT_VISITOR_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/visitor_default_avatar.png";
public static final String DEFAULT_VISITOR_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/visitor_default_avatar.png";
/**
* default uniapp avatar
* 默认UNIAPP头像
*/
public static final String DEFAULT_UNIAPP_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/uniapp_default_avatar.png";
public static final String DEFAULT_UNIAPP_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/uniapp_default_avatar.png";
/**
* default im avatar
* 默认IM注册用户头像
*/
public static final String DEFAULT_USER_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/visitor_default_avatar.png";
public static final String DEFAULT_USER_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/visitor_default_avatar.png";
/**
* default web avatar
* web访客默认头像
*/
public static final String DEFAULT_WEB_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_WEB_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default wap avatar
* wap访客默认头像
*/
public static final String DEFAULT_WAP_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_WAP_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default wechat avatar
* wechat访客默认头像-公众号
*/
public static final String DEFAULT_WECHAT_MP_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_WECHAT_MP_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default wechat mini avatar
* wechat访客默认头像-小程序
*/
public static final String DEFAULT_WECHAT_MINI_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_WECHAT_MINI_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default wechat kf avatar
* wechat访客默认头像-微信客服
*/
public static final String DEFAULT_WECHAT_KEFU_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_WECHAT_KEFU_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default android avatar
* 安卓访客默认头像
*/
public static final String DEFAULT_ANDROID_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/android_default_avatar.png";
public static final String DEFAULT_ANDROID_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/android_default_avatar.png";
/**
* default ios avatar
* 苹果访客默认头像
*/
public static final String DEFAULT_IOS_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/apple_default_avatar.png";
public static final String DEFAULT_IOS_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/apple_default_avatar.png";
/**
* default flutter-android avatar
* Flutter-安卓访客默认头像
*/
public static final String DEFAULT_FLUTTER_ANDROID_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/android_default_avatar.png";
public static final String DEFAULT_FLUTTER_ANDROID_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/android_default_avatar.png";
/**
* default flutter-ios avatar
* Flutter-苹果访客默认头像
*/
public static final String DEFAULT_FLUTTER_IOS_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/apple_default_avatar.png";
public static final String DEFAULT_FLUTTER_IOS_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/apple_default_avatar.png";
/**
* default flutter-web avatar
* Flutter-WEB访客默认头像
*/
public static final String DEFAULT_FLUTTER_WEB_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/chrome_default_avatar.png";
public static final String DEFAULT_FLUTTER_WEB_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/chrome_default_avatar.png";
/**
* default system avatar
* 默认系统头像
*/
public static final String DEFAULT_SYSTEM_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/system_default_avatar.png";
public static final String DEFAULT_SYSTEM_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/system_default_avatar.png";
/**
* default work group avatar
* 默认工作组头像
*/
public static final String DEFAULT_WORK_GROUP_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/workgroup_default_avatar.png";
public static final String DEFAULT_WORK_GROUP_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/workgroup_default_avatar.png";
/**
* default group avatar
@@ -136,10 +136,10 @@ public class AvatarConsts {
public static final String DEFAULT_GROUP_AVATAR_URL = "https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/group_default_avatar.png";
// 文件助手头像
public static final String DEFAULT_FILE_ASISTANT_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/file_asistant_avatar.png";
public static final String DEFAULT_FILE_ASISTANT_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/file_asistant_avatar.png";
// 系统通知-公众号头像
public static final String DEFAULT_SYSTEM_NOTIFICATION_AVATAR_URL = "https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/notification.png";
public static final String DEFAULT_SYSTEM_NOTIFICATION_AVATAR_URL = "https://cdn.weiyuai.cn/avatars/notification.png";
/**
* 测试头像:

View File

@@ -1,10 +1,24 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-02 21:48:19
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-04 11:57:42
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.constant;
import java.io.File;
// import java.io.File;
/**
*
* @author xiaper.io
* @author bytedesk.com
*/
public class BdConstants {
@@ -12,238 +26,19 @@ public class BdConstants {
private BdConstants() {
}
/**
* 项目名称
*/
public static final String PROJECT_NAME = "ByteDesk";
public static final boolean IS_DEBUG = false;
// bytedesk
public static final String PLATFORM_BYTEDESK = "BYTEDESK";
// public static final boolean IS_DEBUG = false;
// 空字符串
public static final String EMPTY_STRING = "";
public static final String EMPTY_JSON_STRING = "{}";
/**
* Path separator.
*/
public static final String FILE_SEPARATOR = File.separator;
// public static final String DEFAULT_USER_DESCRIPTION = "user default description";
/**
* 是否私有部署
*/
public static final boolean IS_PRIVATE_DEPLOY = false; // 私有部署
public static final String PRIVATE_DEPLOY_VALIDEDATE = "2022-09-01 00:00:00"; // 到期时间
public static final int PRIVATE_DEPLOY_AGENTCOUNT = 2; // 客服数量
/**
* 创建web默认值
*/
public static final String DEFAULT_ADMIN_NICKNAME = "管理员";
public static final String DEFAULT_WEB_NAME = "默认网站";
public static final String DEFAULT_WEB_URL = "www.bytedesk.com";
public static final String DEFAULT_AT_EMAIL = "@email.com";
// public static final String DEFAULT_AT_WECHAT = "@wechat.qq.com";
public static final String DEFAULT_BROWSE_START = " 网页浏览开始";
public static final String DEFAULT_BROWSE_END = " 网页浏览结束";
public static final String DEFAULT_BROWSE_INVITE = "邀请访客会话";
public static final String DEFAULT_ROBOT_NICKNAME = "智能客服";
public static final String DEFAULT_ROBOT_DESCRIPTION = "让客户服务更智能";
public static final String DEFAULT_ONLINE = "上线";
public static final String DEFAULT_OFFLINE = "离线";
public static final String DEFAULT_QUEUE_LEAVE = "退出排队";
//
public static final String DEFAULT_TICKET_CONTENT = "ticketInit";
public static final String DEFAULT_TICKET_IGNORE_CLOSE_TIP = "忽略工单-关闭会话";
public static final String DEFAULT_TICKET_DONE_CLOSE_TIP = "解决工单-关闭会话";
public static final String DEFAULT_TICKET_CLOSE_TIP = "访客关闭工单";
// 此uid为系统通知用户uid
public static final String SYSTEM_NOTIFICATION_USER_UUID = "201808221551195";
/**
* 创建workgroup默认值
*/
public static final String DEFAULT_WORK_GROUP_NAME = "默认工作组";
public static final String DEFAULT_WORK_GROUP_SLOGAN = "全心全意为您服务";
public static final String DEFAULT_WORK_GROUP_ROBOT_TIP = "您好, 我是智能机器人, 有什么可以帮您的?";
public static final String DEFAULT_WORK_GROUP_WELCOME_TIP = "您好,有什么可以帮您的?";
public static final String DEFAULT_WORK_GROUP_ROBOT_WELCOME_TIP = "您好,我是智能助理,请直接输入问题";
/**
* TODO: 支持管理后台自定义
*/
public static final String DEFAULT_WORK_GROUP_ACCEPT_TIP = "您好,有什么可以帮您的?";
/**
* TODO: 支持管理后台自定义
*/
public static final String DEFAULT_WORK_GROUP_NON_WORKING_TIME_TIP = "当前非工作时间,请自助查询或留言";
/**
* TODO: 支持管理后台自定义
*/
public static final String DEFAULT_WORK_GROUP_OFFLINE_TIP = "当前无客服在线,请自助查询或留言";
public static final String DEFAULT_WORK_GROUP_DESCRIPTION = "DEFAULT_WORKGROUP_DESCRIPTION";
public static final String DEFAULT_WORK_GROUP_ABOUT = "关于我们";
public static final String DEFAULT_WORK_GROUP_AGENT_CLOSE_TIP = "客服关闭会话";
public static final String DEFAULT_WORK_GROUP_VISITOR_CLOSE_TIP = "访客关闭会话";
public static final String DEFAULT_WORK_GROUP_AUTO_CLOSE_TIP = "长时间没有对话,系统自动关闭会话";
public static final String DEFAULT_WORK_GROUP_NON_WORKING_TIME_CLOSE_TIP = "非工作时间关闭会话";
public static final String DEFAULT_WORK_GROUP_OFFLINE_CLOSE_TIP = "客服离线关闭会话";
public static final String DEFAULT_WORK_GROUP_INVITE_RATE = "邀请评价";
public static final String DEFAULT_WORK_GROUP_VISITOR_RATE = "已评价";
public static final String DEFAULT_WORK_GROUP_QUESTIONNAIRE_TIP = "咨询前问卷";
public static final String DEFAULT_WORK_GROUP_ROBOT_ANSWER_NOT_FOUND = "抱歉,未找到相应答案";
public static final String DEFAULT_WORK_GROUP_ROBOT_MAX_QUEUE_COUNT_EXCEED_TIP = "人工繁忙,请稍后再试";
public static final String DEFAULT_WORK_GROUP_ROBOT_MAX_QUEUE_SECOND_EXCEED_TIP = "很抱歉,目前人工服务全忙,请稍后";
public static final String DEFAULT_WORK_GROUP_ROBOT_TO_AGENT_TIP = "转人工客服,关闭机器人会话";
public static final String DEFAULT_WORK_GROUP_DEFAULT_TOP_TIP = "DEFAULT_WORKGROUP_TOP_TIP";
/**
* 工作组
*/
public static final String DEFAULT_WORK_GROUP_REQUEST_TIP = "请求会话"; // = "requestThread";
public static final String DEFAULT_WORK_GROUP_RE_REQUEST_TIP = "继续会话"; // = "continueThread";
public static final String DEFAULT_WORK_GROUP_JOIN_THREAD = "joinThread";
public static final String DEFAULT_WORK_GROUP_TRANSFER = "transferThread";
public static final String DEFAULT_WORK_GROUP_TRANSFER_ACCEPT = "acceptTransferThread";
public static final String DEFAULT_WORK_GROUP_TRANSFER_REJECT = "rejectTransferThread";
public static final String DEFAULT_WORK_GROUP_INVITE = "inviteThread";
public static final String DEFAULT_WORK_GROUP_INVITE_VIDEO = "inviteVideoThread";
public static final String DEFAULT_WORK_GROUP_INVITE_AUDIO = "inviteAudioThread";
public static final String DEFAULT_WORK_GROUP_INVITE_ACCEPT = "acceptInviteThread";
public static final String DEFAULT_WORK_GROUP_INVITE_REJECT = "rejectInviteThread";
public static final String DEFAULT_WORK_GROUP_QUEUE_ACCEPT = "joinQueueThread";
public static final String DEFAULT_WORK_GROUP_QUEUE_IGNORE = "ignoreQueueThread";
public static final String DEFAULT_WORK_GROUP_QUEUE_TIMEOUT = "timeoutQueueThread";
//
public static final String DEFAULT_VISITOR_CONNECT = "visitorConnect";
public static final String DEFAULT_VISITOR_DISCONNECT = "visitorDisconnect";
/**
* 群组
*/
public static final String DEFAULT_GROUP_DESCRIPTION = "群组描述:这个家伙很懒,什么也没写";
public static final String DEFAULT_GROUP_ANNOUNCEMENT = "群组公告:这个家伙很懒,什么也没写";
/**
* 请求一对一会话
*/
public static final String DEFAULT_VISITOR_REQUEST_THREAD = " 请求会话";
public static final String DEFAULT_AGENT_OFFLINE_TIP = "当前客服不在线,请留言";
public static final String DEFAULT_AGENT_WELCOME_TIP = "您好,有什么可以帮您的?";
public static final String DEFAULT_AGENT_DESCRIPTION = "DEFAULT_AGENT_DESCRIPTION";
public static final String DEFAULT_AGENT_AUTO_REPLY_CONTENT = "无自动回复";
/**
* 微信公众号默认关注提示语
*/
public static final String DEFAULT_WECHAT_WELCOME_TIP = "欢迎关注";
// 权限常量
public static final String AUTHORITY_VISITOR_CHAT = "visitor_chat";
/**
* 通过淘宝接口查询ip所属城市
* http://ip.taobao.com/service/getIpInfo.php?ip=60.186.185.142
*/
public static final String IP_INFO_TAOBAO_URL = "http://ip.taobao.com/service/getIpInfo.php?ip=";
/**
* 私有部署用户验证有效性URL
*/
public static final String PRIVATE_SERVER_VALIDATE_URL = "https://api.bytedesk.com/visitor/api/server/validate?uId=";
/**
* 时间格式
*/
public static final String DATETIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 微信授权事件类型
*/
public static final String WECHAT_OPEN_PLATFORM_INFO_TYPE_AUTHORIZED = "authorized";
public static final String WECHAT_OPEN_PLATFORM_INFO_TYPE_UNAUTHORIZED = "unauthorized";
public static final String WECHAT_OPEN_PLATFORM_INFO_TYPE_UPDATE_AUTHORIZED = "updateauthorized";
public static final String WECHAT_OPEN_PLATFORM_INFO_TYPE_COMPONENT_VERIFY_TICKET = "component_verify_ticket";
/**
* 跳转去授权URL
*/
public static final String WECHAT_OPEN_PLATFORM_REDIRECT_URI = "https://wechat.bytedesk.com/wechat/mp/oauth/redirect/";
/**
* 授权事件接收URL
*/
public static final String WECHAT_OPEN_PLATFORM_OAUTH_CALLBACK_URI = "https://wechat.bytedesk.com/wechat/mp/oauth/callback";
/**
* 微信客服授权回调URL
*/
public static final String WECHAT_KEFU_OAUTH_CALLBACK_URI = "https://wechat.bytedesk.com/wechat/kefu/oauth/callback";
/**
* 绑定公众后跳转URL
*/
// public static final String WECHAT_OPEN_PLATFORM_ADMIN_CALLBACK_URL =
// ".bytedesk.com/admin#/admin/setting/app";
public static final String WECHAT_OPEN_PLATFORM_ADMIN_CALLBACK_URL = "https://www.bytedesk.com/antv/kefu/channel-list";
/**
* 访客验证URL
*/
public static final String VISITOR_TOKEN_URL = "/visitor/token";
public static final String VISITOR_TOKEN_USERNAME = "username";
public static final String VISITOR_TOKEN_PASSWORD = "password";
/**
* 短信验证URL
*/
public static final String MOBILE_TOKEN_URL = "/mobile/token";
public static final String MOBILE_TOKEN_MOBILE = "mobile";
public static final String MOBILE_TOKEN_CODE = "code";
/**
* 邮箱验证URL
*/
public static final String EMAIL_TOKEN_URL = "/email/token";
public static final String EMAIL_TOKEN_EMAIL = "email";
public static final String EMAIL_TOKEN_CODE = "code";
/**
*
*/
public static final String SCAN_URL = "/scan/token";
public static final String SCAN_USERNAME = "username";
public static final String SCAN_CODE = "code";
/**
* 微信登录URL
*/
public static final String WECHAT_TOKEN_URL = "/wechat/token";
public static final String WECHAT_TOKEN_GRANT_TYPE = "wechat";
public static final String WECHAT_TOKEN_UNIONID = "unionid";
/**
* 企业微信登录URL
*/
public static final String WECHAT_WORK_TOKEN_URL = "/wechat/work/token";
public static final String WECHAT_WORK_TOKEN_GRANT_TYPE = "wechat_work";
public static final String WECHAT_WORK_TOKEN_USERID = "userid";
/**
*
*/
// public static final String TOPIC_PROTOBUF_PREFIX = "protobuf/";
// public static final String TOPIC_JSON_PREFIX = "json/";
// bytedesk
public static final String PLATFORM_BYTEDESK = "BYTEDESK";
/**
* huawei push
*/
public static final String HW_PUSH_TOKEN_SERVER = "https://oauth-login.cloud.huawei.com/oauth2/v3/token";
public static final String HW_PUSH_OPEN_URL = "https://push-api.cloud.huawei.com";
//
public static final String TOKEN = "token";
/**
* 当无客服在线时,是跳转留言表单 or 使用对话窗口留言
*/
public static final String LEAVE_MESSAGE_TYPE_FORM = "form";
public static final String LEAVE_MESSAGE_TYPE_CHAT = "chat";
//
// 默认组织uid
public static final String DEFAULT_ORGANIZATION_UID = "df_org_uid";
public static final String DEFAULT_AGENT_UID = "df_ag_uid";
public static final String DEFAULT_WORKGROUP_UID = "df_wg_uid";
public static final String DEFAULT_ROBOT_UID = "df_rt_uid";
public static final String DEFAULT_FILE_ASISTANT_UID = "df_fa_uid";
public static final String DEFAULT_SYSTEM_UID = "df_sys_uid";
}

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-07-06 13:15:13
* @LastEditTime: 2024-08-02 07:46: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.
@@ -59,14 +59,18 @@ public class I18Consts {
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_TODO = I18N_PREFIX + "todo";
//
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 = I18N_PREFIX + "llm.prompt";
public static final String I18N_ROBOT_REPLY = I18N_PREFIX + "robot.reply";
public static final String I18N_ROBOT_NO_REPLY = I18N_PREFIX + "robot.noreply";
//
public static final String I18N_ADMIN = I18N_PREFIX + "admin";
public static final String I18N_ADMIN_DESCRIPTION = I18N_PREFIX + "admin.description";
public static final String I18N_MEMBER = I18N_PREFIX + "member";
public static final String I18N_MEMBER_DESCRIPTION = I18N_PREFIX + "member.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"; // 感谢

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-25 13:07:20
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-26 17:06:43
* @LastEditTime: 2024-07-27 21:59:49
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -15,45 +15,35 @@
package com.bytedesk.core.enums;
public enum ClientEnum {
SYSTEM("system"),
SYSTEM_AUTO("system_auto"), // auto reply
SYSTEM_BOT("system_bot"), // robot reply
WEB("web"),
H5("h5"),
IOS("ios"),
ANDROID("android"),
ELECTRON("electron"),
LINUX("linux"),
MACOS("macos"),
WINDOWS("windows"),
FLUTTER("flutter"),
FLUTTER_WEB("flutter_web"),
FLUTTER_ANDROID("flutter_android"),
FLUTTER_IOS("flutter_ios"),
UNI("uni"),
UNI_WEB("uni_web"),
UNI_ANDROID("uni_android"),
UNI_IOS("uni_ios"),
WECHAT_MINI("wechat_mini"),
WECHAT_MP("wechat_mp"),
WECHAT_WORK("wechat_work"),
WECHAT_KEFU("wechat_kefu"),
SYSTEM,
SYSTEM_AUTO, // auto reply
SYSTEM_BOT, // robot reply
WEB,
H5,
IOS,
ANDROID,
ELECTRON,
LINUX,
MACOS,
WINDOWS,
FLUTTER,
FLUTTER_WEB,
FLUTTER_ANDROID,
FLUTTER_IOS,
UNI,
UNI_WEB,
UNI_ANDROID,
UNI_IOS,
WECHAT_MINI,
WECHAT_MP,
WECHAT_WORK,
WECHAT_KEFU,
;
private final String value;
ClientEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
// 根据字符串查找对应的枚举常量
public static ClientEnum fromValue(String value) {
for (ClientEnum type : ClientEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-07 14:19:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-07 14:20:31
* @LastEditTime: 2024-07-24 14:12:14
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -15,27 +15,17 @@
package com.bytedesk.core.enums;
public enum LanguageEnum {
EN,//("en"),
ZH_CN,//("zh-cn"),
ZH_TW,//("zh-tw");
EN,
ZH_CN,
ZH_TW;
// private final String value;
// LanguageEnum(String value) {
// this.value = 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.name().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-06-20 15:55:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-20 16:27:38
* @LastEditTime: 2024-07-24 14:12: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.
@@ -15,27 +15,17 @@
package com.bytedesk.core.enums;
public enum LevelEnum {
PLATFORM("platform"),
ORGNIZATION("organization"),
DEPARTMENT("department"),
WORKGROUP("workgroup"),
GROUP("group"),
USER("user");
private final String value;
LevelEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
PLATFORM,
ORGNIZATION,
DEPARTMENT,
WORKGROUP,
GROUP,
USER;
// 根据字符串查找对应的枚举常量
public static LevelEnum fromValue(String value) {
for (LevelEnum type : LevelEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}

View File

@@ -1,30 +1,20 @@
package com.bytedesk.core.enums;
public enum PlatformEnum {
BYTEDESK("bytedesk"),
LIANGSHIBAO("liangshibao"),
ZHAOBIAO("zhaobiao"),
MEIYU("meiyu"),
TIKU("tiku");
private final String value;
PlatformEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
BYTEDESK,
LIANGSHIBAO,
ZHAOBIAO,
MEIYU,
TIKU;
// 根据字符串查找对应的枚举常量
public static PlatformEnum fromValue(String value) {
for (PlatformEnum type : PlatformEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}
throw new IllegalArgumentException("No QuickReplyPlatformEnum constant with value: " + value);
throw new IllegalArgumentException("No PlatformEnum constant with value: " + value);
}
}

View File

@@ -0,0 +1,38 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 11:35:47
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-17 11:36:59
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;
// 通用型事件
public class GenericApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
private T object;
public GenericApplicationEvent(Object source, T object) {
super(source);
this.object = object;
}
public T getObject() {
return object;
}
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(object));
}
}

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-20 11:53:29
* @LastEditTime: 2024-07-26 18:32:40
* @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.
@@ -101,6 +101,8 @@ public class GlobalControllerAdvice {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<?> handleRuntimeException(RuntimeException e) {
// 方便测试,打印异常堆栈信息
e.printStackTrace();
return ResponseEntity.ok().body(JsonResult.error(e.getMessage()));
}

View File

@@ -1,66 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-20 14:29:37
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-22 09:06: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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 org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.message.MessageTypeEnum;
import com.bytedesk.core.rbac.organization.Organization;
import com.bytedesk.core.rbac.organization.OrganizationCreateEvent;
// import com.bytedesk.core.rbac.user.User;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@AllArgsConstructor
public class FaqEventListener {
private final FaqService faqService;
@Order(3)
@EventListener
public void onOrganizationCreateEvent(OrganizationCreateEvent event) {
Organization organization = (Organization) event.getSource();
String orgUid = organization.getUid();
log.info("faq - organization created: {}", organization.getName());
//
FaqRequest faqDemo1 = FaqRequest.builder()
.title(I18Consts.I18N_FAQ_DEMO_TITLE_1)
.content(I18Consts.I18N_FAQ_DEMO_CONTENT_1)
.type(MessageTypeEnum.TEXT.getValue())
.categoryUid(orgUid + I18Consts.I18N_FAQ_CATEGORY_DEMO_1)
.orgUid(orgUid)
.build();
faqDemo1.setUid(orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_1);
faqService.create(faqDemo1);
//
FaqRequest faqDemo2 = FaqRequest.builder()
.title(I18Consts.I18N_FAQ_DEMO_TITLE_2)
.content(I18Consts.I18N_FAQ_DEMO_CONTENT_2)
.type(MessageTypeEnum.IMAGE.getValue())
.categoryUid(orgUid + I18Consts.I18N_FAQ_CATEGORY_DEMO_2)
.orgUid(orgUid)
.build();
faqDemo2.setUid(orgUid + I18Consts.I18N_FAQ_DEMO_TITLE_2);
faqService.create(faqDemo2);
//
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-05 14:15:17
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-27 11:33:19
* @LastEditTime: 2024-07-31 12:29: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.
@@ -41,9 +41,7 @@ public class IpController {
@PostMapping("/block")
public ResponseEntity<?> blockIp(@RequestBody IpRequest request) {
ipService.blockIp(request);
return ResponseEntity.ok(JsonResult.success());
}
@@ -69,7 +67,6 @@ public class IpController {
*/
@GetMapping("/")
public JsonResult<?> ip(HttpServletRequest request) {
return new JsonResult<>("your ip", 200, IpUtils.clientIp(request));
}
@@ -97,7 +94,7 @@ public class IpController {
}
/**
* http://127.0.0.1:9003/ip/api/v1/ip/location?ip=103.46.244.251
* http://127.0.0.1:9003/ip/api/v1/ip/location?ip=202.106.212.226
*
* @param request
* @return
@@ -130,7 +127,7 @@ public class IpController {
}
// for testing
// http://127.0.0.1:9003/ip/api/v1/ip/province?ip=103.46.244.251
// http://127.0.0.1:9003/ip/api/v1/ip/province?ip=202.106.212.226
@GetMapping("/ip/province")
public JsonResult<?> ipProvince(@RequestParam String ip) {
@@ -140,7 +137,7 @@ public class IpController {
String location = ipService.getIpLocation(ip);
//
String[] locals = location.split("\\|");
log.info("locals {}", (Object[]) locals); // Cast to Object[] to confirm the non-varargs invocation
log.info("location {} locals {}", location, (Object[]) locals); // Cast to Object[] to confirm the non-varargs invocation
String province = "";
if (locals.length > 2) {
if (locals[2].equals("0")) {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-16 13:28:03
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-27 12:15:58
* @LastEditTime: 2024-07-10 08:35:08
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -221,15 +221,16 @@ public class IpService {
// TODO: 昵称国际化:英语、中文、繁体、日文
public String createVisitorNickname(HttpServletRequest request) {
String location = getIpLocation(request);
// TODO: 修改昵称后缀数字为从1~递增
String randomId = uidUtils.getCacheSerialUid();
String ip = getIp(request);
String location = getIpLocation(ip);
// uidUtils.getCacheSerialUid(); // TODO: 修改昵称后缀数字为从1~递增
String randomId = "[" + ip + "]";
// location: "国家|区域|省份|城市|ISP"
// location: "中国|0|湖北省|武汉市|联通"
// 0|0|0|内网IP|内网IP
String[] locals = location.split("\\|");
// log.info("locals {}", (Object[]) locals); // Cast to Object[] to confirm the
log.info("ip {} location {} locals {}", ip, location, (Object[]) locals); // Cast to Object[] to confirm the
// non-varargs invocation
if (locals.length > 2) {
if (locals[2].equals("0")) {
@@ -254,6 +255,7 @@ public class IpService {
return ipRepository.save(ip);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}

View File

@@ -15,25 +15,15 @@
package com.bytedesk.core.ip;
public enum IpTypeEnum {
WHITELIST("whichlist"),
WHITERANGE("whiterange"),
BLACKLIST("blacklist"),
BLACKRANGE("blackrange");
private final String value;
IpTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
WHITELIST,
WHITERANGE,
BLACKLIST,
BLACKRANGE;
// 根据字符串查找对应的枚举常量
public static IpTypeEnum fromValue(String value) {
for (IpTypeEnum type : IpTypeEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
if (type.name().equalsIgnoreCase(value)) {
return type;
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-05 14:17:04
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-05 14:34:09
* @LastEditTime: 2024-07-13 19:11: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.

View File

@@ -0,0 +1,57 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-16 17:48:50
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-19 15:00: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.kaptcha;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Service;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
// import lombok.extern.slf4j.Slf4j;
/**
* TODO: 用Redis替代
*/
// @Slf4j
@Service
// @AllArgsConstructor
public class KaptchaCacheService {
// 验证码5分钟过期
Cache<String, String> kaptchaCache = Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
public void putKaptcha(String key, String value) {
kaptchaCache.put(key, value);
}
public Boolean hasKaptcha(String key) {
return kaptchaCache.getIfPresent(key) != null;
}
public String getKaptcha(String key) {
return kaptchaCache.getIfPresent(key);
}
public Boolean checkKaptcha(String key, String value) {
String cachedValue = kaptchaCache.getIfPresent(key);
return cachedValue != null && cachedValue.equals(value);
}
public void removeKaptcha(String key) {
kaptchaCache.invalidate(key);
}
}

View File

@@ -0,0 +1,97 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-08 23:49:59
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-16 11:20: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署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.kaptcha;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import static com.google.code.kaptcha.Constants.*;
@Configuration
public class KaptchaConfig {
@Bean(name = "captchaProducer")
public DefaultKaptcha getKaptchaBean() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yesno
properties.setProperty(KAPTCHA_BORDER, "no");
// 验证码文本字符颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "white");
// properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
// 验证码图片宽度 默认为200
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "100");
// 验证码图片高度 默认为50
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "40");
// 验证码文本字符大小 默认为40
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
// KAPTCHA_SESSION_KEY
// properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 验证码文本字符长度 默认为5
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "4");
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple
// 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
// 阴影com.google.code.kaptcha.impl.ShadowGimpy
// properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
//
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
// @Bean(name = "captchaProducerMath")
// public DefaultKaptcha getKaptchaBeanMath() {
// DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// Properties properties = new Properties();
// // 是否有边框 默认为true 我们可以自己设置yesno
// properties.setProperty(KAPTCHA_BORDER, "yes");
// // 边框颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
// // 验证码文本字符颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
// // 验证码图片宽度 默认为200
// properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// // 验证码图片高度 默认为50
// properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// // 验证码文本字符大小 默认为40
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
// // KAPTCHA_SESSION_KEY
// properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
// // 验证码文本生成器
// properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator");
// // 验证码文本字符间距 默认为2
// properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
// // 验证码文本字符长度 默认为5
// properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
// // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
// properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// // 验证码噪点颜色 默认为Color.BLACK
// properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
// // 干扰实现类
// properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
// // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple
// // 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
// // 阴影com.google.code.kaptcha.impl.ShadowGimpy
// properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
// Config config = new Config(properties);
// defaultKaptcha.setConfig(config);
// return defaultKaptcha;
// }
}

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