This commit is contained in:
jack ning
2024-09-23 23:18:46 +08:00
parent 654ad8b074
commit d56590d617
127 changed files with 1348 additions and 1681 deletions

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-17 23:34:04
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-19 16:15:01
* @LastEditTime: 2024-09-19 17:12: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.
@@ -41,8 +41,6 @@ public class AutoReplySettings implements Serializable {
// 自动回复类型
@Builder.Default
// @Enumerated(EnumType.STRING)
// private AutoReplyTypeEnum autoReplyType = AutoReplyTypeEnum.FIXED;
private String autoReplyType = AutoReplyTypeEnum.FIXED.name();
// 固定回复类型所需要字段
@@ -51,8 +49,6 @@ public class AutoReplySettings implements Serializable {
// 自动回复内容类型
@Builder.Default
// @Enumerated(EnumType.STRING)
// private MessageTypeEnum autoReplyContentType = MessageTypeEnum.TEXT;
private String autoReplyContentType = MessageTypeEnum.TEXT.name();
// 自动回复内容

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-08-27 13:53:22
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-09-07 17:11:09
* @LastEditTime: 2024-09-20 14:55: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.
@@ -138,9 +138,6 @@ public class KnowledgebaseEventListener {
kownledgebaseRequestTaboo.setType(KnowledgebaseTypeEnum.TABOO.name());
kownledgebaseRequestTaboo.setOrgUid(orgUid);
knowledgebaseService.create(kownledgebaseRequestTaboo);
//
//
}
@EventListener
@@ -178,7 +175,7 @@ public class KnowledgebaseEventListener {
return;
}
String query = messageProtobuf.getContent();
log.info("kb processMessage {}", query);
// log.info("kb processMessage {}", query);
//
ThreadProtobuf thread = messageProtobuf.getThread();
if (thread == null) {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 22:59:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-27 22:04:31
* @LastEditTime: 2024-09-20 14:56: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.
@@ -168,6 +168,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
return;
}
//
String orgUid = BdConstants.DEFAULT_ORGANIZATION_UID;
KnowledgebaseRequest kownledgebaseRequeqstQuickReplyPlatform = KnowledgebaseRequest.builder()
.name(KnowledgebaseConsts.KB_PLATFORM_NAME)
.descriptionHtml(KnowledgebaseConsts.KB_DESCRIPTION)
@@ -177,7 +178,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
kownledgebaseRequeqstQuickReplyPlatform.setUid(BdConstants.DEFAULT_KB_UID);
kownledgebaseRequeqstQuickReplyPlatform.setType(KnowledgebaseTypeEnum.QUICKREPLY.name());
// 方便超级管理员加载,避免重新写一个接口拉取
kownledgebaseRequeqstQuickReplyPlatform.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequeqstQuickReplyPlatform.setOrgUid(orgUid);
create(kownledgebaseRequeqstQuickReplyPlatform);
////////////////////////////////////////////////////////////
@@ -188,7 +189,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequestHelpdoc.setType(KnowledgebaseTypeEnum.HELPDOC.name());
kownledgebaseRequestHelpdoc.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequestHelpdoc.setOrgUid(orgUid);
create(kownledgebaseRequestHelpdoc);
//
KnowledgebaseRequest kownledgebaseRequestLlm = KnowledgebaseRequest.builder()
@@ -197,7 +198,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequestLlm.setType(KnowledgebaseTypeEnum.LLM.name());
kownledgebaseRequestLlm.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequestLlm.setOrgUid(orgUid);
create(kownledgebaseRequestLlm);
//
KnowledgebaseRequest kownledgebaseRequestKeyword = KnowledgebaseRequest.builder()
@@ -206,7 +207,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequestKeyword.setType(KnowledgebaseTypeEnum.KEYWORD.name());
kownledgebaseRequestKeyword.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequestKeyword.setOrgUid(orgUid);
create(kownledgebaseRequestKeyword);
//
KnowledgebaseRequest kownledgebaseRequeqstFaq = KnowledgebaseRequest.builder()
@@ -215,7 +216,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequeqstFaq.setType(KnowledgebaseTypeEnum.FAQ.name());
kownledgebaseRequeqstFaq.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequeqstFaq.setOrgUid(orgUid);
create(kownledgebaseRequeqstFaq);
//
KnowledgebaseRequest kownledgebaseRequeqstAutoReply = KnowledgebaseRequest.builder()
@@ -224,7 +225,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequeqstAutoReply.setType(KnowledgebaseTypeEnum.AUTOREPLY.name());
kownledgebaseRequeqstAutoReply.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequeqstAutoReply.setOrgUid(orgUid);
create(kownledgebaseRequeqstAutoReply);
//
KnowledgebaseRequest kownledgebaseRequeqstQuickReply = KnowledgebaseRequest.builder()
@@ -233,7 +234,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequeqstQuickReply.setType(KnowledgebaseTypeEnum.QUICKREPLY.name());
kownledgebaseRequeqstQuickReply.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequeqstQuickReply.setOrgUid(orgUid);
create(kownledgebaseRequeqstQuickReply);
//
KnowledgebaseRequest kownledgebaseRequestTaboo = KnowledgebaseRequest.builder()
@@ -242,7 +243,7 @@ public class KnowledgebaseService extends BaseService<Knowledgebase, Knowledgeba
.language(LanguageEnum.ZH_CN.name())
.build();
kownledgebaseRequestTaboo.setType(KnowledgebaseTypeEnum.TABOO.name());
kownledgebaseRequestTaboo.setOrgUid(BdConstants.DEFAULT_ORGANIZATION_UID);
kownledgebaseRequestTaboo.setOrgUid(orgUid);
create(kownledgebaseRequestTaboo);
//

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-22 16:12:30
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-27 17:46:30
* @LastEditTime: 2024-09-20 13:34: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.
@@ -48,15 +48,14 @@ public class QuickReply extends BaseEntity {
@Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT)
private String content;
// 快捷键
private String shortCut;
@Builder.Default
// @Enumerated(EnumType.STRING)
@Column(name = "reply_type", nullable = false)
// private MessageTypeEnum type = MessageTypeEnum.TEXT;
private String type = MessageTypeEnum.TEXT.name();
@Builder.Default
// @Enumerated(EnumType.STRING)
// private LevelEnum level = LevelEnum.ORGNIZATION;
private String level = LevelEnum.ORGNIZATION.name();
private String categoryUid; // 文章分类

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 22:59:48
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-27 16:18:05
* @LastEditTime: 2024-09-21 11:26:41
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -34,6 +34,8 @@ public class QuickReplyRequest extends BaseRequest {
private String content;
private String shortCut;
// @Builder.Default
// private String type;
// private MessageTypeEnum type = MessageTypeEnum.TEXT;

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 23:00:00
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-27 17:46:40
* @LastEditTime: 2024-09-21 11:26:47
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -35,6 +35,8 @@ public class QuickReplyResponse extends BaseResponse {
private String content;
private String shortCut;
private String type;
private String level;

View File

@@ -54,10 +54,10 @@ public class BaseServiceSettings implements Serializable {
*/
@NotBlank
private boolean showTopTip = false;
// 公告
@NotBlank
private String topTip = I18Consts.I18N_TOP_TIP;
// TODO: 公告显示日期范围
// 满意度评价设置
// show rate btn on chat toolbar

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-07-28 06:48:10
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-09-07 16:56:14
* @LastEditTime: 2024-09-16 14:57:41
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -70,8 +70,6 @@ public class UploadEventListener {
private final RedisPubsubService redisPubsubService;
// private final MessageService messageService;
private final UidUtils uidUtils;
@EventListener

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-19 17:02:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-07-28 12:17:58
* @LastEditTime: 2024-09-16 15:42: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.
@@ -32,10 +32,12 @@ import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
*
*/
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/file")
@@ -45,23 +47,26 @@ public class UploadFilePreview {
/**
* 浏览器下载文件
* http://127.0.0.1:9003/file/download/20240319162820_img-service2.png
* http://127.0.0.1:9003/file/download/2024/09/16/20240319162820_img-service2.png
*
* @param filename
* @return
*/
@GetMapping("/download/{filename:.+}")
@Deprecated
@GetMapping("/download/{yyyy}/{MM}/{dd}/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> download(@PathVariable String filename) throws UnsupportedEncodingException {
public ResponseEntity<Resource> download(
@PathVariable(name = "yyyy") String year,
@PathVariable(name = "MM") String month,
@PathVariable(name = "dd") String day,
@PathVariable String filename) throws UnsupportedEncodingException {
log.info("year {}, month {}, day {}, filename: {}", year, month, day, filename);
Resource fileResource = uploadService.loadAsResource(filename);
if (fileResource == null) {
return ResponseEntity.notFound().build();
}
// 对文件名进行URL编码以确保中文字符能够正确传输
String encodedFilename = URLEncoder.encode(fileResource.getFilename(), "UTF-8").replace("+", "%20");
// 设置HTTP响应头包含经过编码的文件名
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", encodedFilename);
@@ -71,16 +76,21 @@ public class UploadFilePreview {
/**
* 浏览器预览文件,或放到 <img src> 标签中在线展示
* http://127.0.0.1:9003/file/20240319162820_img-service2.png
* http://127.0.0.1:9003/file/2024/09/16/20240916144702_身份证-背面.jpg
*
* @param filename
* @return
* @throws IOException
*/
@GetMapping("/{filename:.+}")
@GetMapping("/{yyyy}/{MM}/{dd}/{filename:.+}")
@ResponseBody
public void preview(@PathVariable String filename, HttpServletResponse response) throws IOException {
public void preview(
@PathVariable(name = "yyyy") String year,
@PathVariable(name = "MM") String month,
@PathVariable(name = "dd") String day,
@PathVariable String filename,
HttpServletResponse response) throws IOException {
log.info("year {}, month {}, day {}, filename: {}", year, month, day, filename);
Resource fileResource = uploadService.loadAsResource(filename);
// 文件预览
@@ -102,4 +112,57 @@ public class UploadFilePreview {
fileInputStream.close();
}
/////////////// 旧版本
// http://127.0.0.1:9003/file/download/20240319162820_img-service2.png
@Deprecated
@GetMapping("/download/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> downloadOld(@PathVariable String filename) throws UnsupportedEncodingException {
Resource fileResource = uploadService.loadAsResource(filename);
if (fileResource == null) {
return ResponseEntity.notFound().build();
}
// 对文件名进行URL编码以确保中文字符能够正确传输
String encodedFilename = URLEncoder.encode(fileResource.getFilename(), "UTF-8").replace("+", "%20");
// 设置HTTP响应头包含经过编码的文件名
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", encodedFilename);
return ResponseEntity.ok().headers(headers).body(fileResource);
}
// http://127.0.0.1:9003/file/20240319162820_img-service2.png
@Deprecated
@GetMapping("/{filename:.+}")
@ResponseBody
public void previewOld(
@PathVariable String filename,
HttpServletResponse response) throws IOException {
log.info("filename: {}", filename);
Resource fileResource = uploadService.loadAsResourceOld(filename);
// 文件预览
File file = fileResource.getFile();
FileInputStream fileInputStream = new FileInputStream(file);
// 清空response
response.reset();
// 2、设置文件下载方式
response.setCharacterEncoding("utf-8");
// response.setContentType("application/pdf");
OutputStream outputStream = response.getOutputStream();
int count = 0;
byte[] buffer = new byte[1024 * 1024];
while ((count = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
outputStream.flush();
outputStream.close();
fileInputStream.close();
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-15 11:35:53
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-08-31 16:03:26
* @LastEditTime: 2024-09-16 15:28: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.
@@ -19,10 +19,12 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
// import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Optional;
import java.util.stream.Stream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.modelmapper.ModelMapper;
import org.springframework.core.io.Resource;
@@ -42,8 +44,10 @@ import com.bytedesk.core.uid.UidUtils;
import com.bytedesk.kbase.upload.storage.UploadStorageException;
import com.bytedesk.kbase.upload.storage.UploadStorageFileNotFoundException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
// https://spring.io/guides/gs/uploading-files
@Slf4j
@Service
@AllArgsConstructor
public class UploadService extends BaseService<Upload, UploadRequest, UploadResponse> {
@@ -86,30 +90,62 @@ public class UploadService extends BaseService<Upload, UploadRequest, UploadResp
}
public String store(MultipartFile file, String fileName) {
// 根据当前日期创建文件夹格式如2021/03/15
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String currentDateFolder = LocalDate.now().format(formatter);
try {
if (file.isEmpty()) {
throw new UploadStorageException("Failed to store empty file.");
}
Path destinationFile = this.uploadDir.resolve(
Paths.get(fileName))
.normalize().toAbsolutePath();
if (!destinationFile.getParent().equals(this.uploadDir.toAbsolutePath())) {
// This is a security check
throw new UploadStorageException(
"Cannot store file outside current directory.");
}
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, destinationFile,
StandardCopyOption.REPLACE_EXISTING);
// 构建包含日期文件夹的文件路径
Path dateFolderPath = this.uploadDir.resolve(currentDateFolder);
Files.createDirectories(dateFolderPath); // 创建日期文件夹(如果不存在)
Path destinationFile = dateFolderPath.resolve(fileName).normalize().toAbsolutePath();
if (!destinationFile.getParent().equals(dateFolderPath.toAbsolutePath())) {
// 这是一个安全检查
throw new UploadStorageException("Cannot store file outside current directory.");
}
return destinationFile.getFileName().toString();
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, destinationFile, StandardCopyOption.REPLACE_EXISTING);
}
// 返回包含日期文件夹的文件名路径
return currentDateFolder + "/" + fileName;
} catch (IOException e) {
throw new UploadStorageException("Failed to store file.", e);
}
}
// public String store(MultipartFile file, String fileName) {
// // TODO: 根据当前日期创建文件夹并存储文件格式如下2021/03/15/fileName
// try {
// if (file.isEmpty()) {
// throw new UploadStorageException("Failed to store empty file.");
// }
// Path destinationFile = this.uploadDir.resolve(
// Paths.get(fileName))
// .normalize().toAbsolutePath();
// if (!destinationFile.getParent().equals(this.uploadDir.toAbsolutePath())) {
// // This is a security check
// throw new UploadStorageException(
// "Cannot store file outside current directory.");
// }
// try (InputStream inputStream = file.getInputStream()) {
// Files.copy(inputStream, destinationFile,
// StandardCopyOption.REPLACE_EXISTING);
// }
// return destinationFile.getFileName().toString();
// } catch (IOException e) {
// throw new UploadStorageException("Failed to store file.", e);
// }
// }
public Stream<Path> loadAll() {
try {
return Files.walk(this.uploadDir, 1)
@@ -120,13 +156,51 @@ public class UploadService extends BaseService<Upload, UploadRequest, UploadResp
}
}
public Path load(String filename) {
return uploadDir.resolve(filename);
}
public Resource loadAsResource(String filename) {
// filename格式为20240916144702_身份证-背面.jpg
// 提取日期部分
String dateString = filename.substring(0, 8);
// 将日期字符串转换为路径格式
String folderDatePart = dateString.substring(0, 4) + "/" + dateString.substring(4, 6) + "/"
+ dateString.substring(6, 8);
// 构建文件夹路径
Path dateFolderPath = this.uploadDir.resolve(folderDatePart);
// 创建日期文件夹(如果不存在)
try {
Path file = load(filename);
Files.createDirectories(dateFolderPath);
} catch (IOException e) {
// 处理异常
e.printStackTrace();
}
// 构建完整的文件路径
Path filePath = dateFolderPath.resolve(filename);
try {
if (Files.exists(filePath)) {
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
throw new UploadStorageFileNotFoundException(
"Could not read file: " + filename);
}
} else {
throw new UploadStorageFileNotFoundException(
"File not found: " + filename);
}
} catch (MalformedURLException e) {
throw new UploadStorageFileNotFoundException("Could not read file: " + filename, e);
}
}
// TODO: 待删除
@Deprecated
public Resource loadAsResourceOld(String filename) {
try {
Path file = uploadDir.resolve(filename);
//load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
@@ -139,7 +213,6 @@ public class UploadService extends BaseService<Upload, UploadRequest, UploadResp
}
}
public void initUploadDir() {
try {
Files.createDirectories(uploadDir);